/* iangreer.com v2: the shared foundation for every page (theme 2.1.0).
   Tokens, type, buttons and links, the corner chrome (name and Menu), the full-screen menu and the
   site footer. The homepage adds home.css; every other page adds site.css.
   Blueprint blue, cool paper, blue-black ink; Archivo only. Brief: scripts/home-v2/BRIEF.md.
   The rules are Blueprint OS (scripts/design-system/brand-book.md); its colour tokens are below (2.2.0). */

/* @font-face for Archivo and Mona Sans lives in the layouts (versioned asset URLs). */

:root {
  --blue: #2340f2;
  --blue-deep: #1a2fc4;
  --paper: #f4f5f7;
  --ink: #0b0e18;
  --ink-soft: #4a5064;
  --on-blue: #ffffff;
  --on-blue-soft: #d9defe;
  --rule: rgba(11, 14, 24, 0.16);
  --rule-strong: #0b0e18;
  --rule-blue: rgba(255, 255, 255, 0.3);
  --blue-text: #2340f2;
  --blue-soft: #e6eafe;
  --focus: var(--blue);
  /* The book's parts, the Jewel palette (2.3.1): scarlet, emerald, amethyst. As saturated as the
     blue and near its lightness, all three carry white type and pass 4.5:1 as text on paper and
     sepia, so each colour is both the fill and the text. They always hold or sit beside the part's
     name and are never a button, a link or decoration: blue is the only colour for things you click.
     The dark reading mode switches the -text and -soft tokens to their night values below. */
  --scarlet: #c92324;  --scarlet-text: #c92324;  --scarlet-soft: #feebe9;  --on-scarlet: #ffffff;
  --emerald: #047554;  --emerald-text: #047554;  --emerald-soft: #dff7eb;  --on-emerald: #ffffff;
  --amethyst: #712a94; --amethyst-text: #712a94; --amethyst-soft: #f7ebff; --on-amethyst: #ffffff;
  --part-business: var(--scarlet); --part-investing: var(--emerald); --part-politics: var(--amethyst);
  --success: var(--blue-text); --warning: #945b00; --danger: var(--scarlet-text);
  --el-bg: #0b0d0f;
  --el-ink: #edeeea;
  --el-soft: #9aa3a8;
  --el-orange: #ff6b2c;
  --g: clamp(16px, 3.4vw, 52px);
  --corner-h: clamp(64px, 7vw, 84px);
  --ease: cubic-bezier(0.23, 1, 0.32, 1);

  /* engine tokens, themed */
  --sc-canvas: var(--paper);
  --sc-surface: #ffffff;
  --sc-ink: var(--ink);
  --sc-ink-soft: var(--ink-soft);
  --sc-accent: var(--blue);
  --sc-accent-ink: #ffffff;
  --sc-font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --sc-font-text: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --sc-font-mono: ui-monospace, "SFMono-Regular", Consolas, monospace;
}

/* The part colours in use (2.3.0, Jewel palette since 2.3.1; Blueprint OS PartTag and PartSection). Anything that names a part
   carries data-part="business|investing|political" and draws from these: --part-fill is the solid
   colour, --part-on the text on it. They appear only as solid colour holding the part's name: the
   book page's part bars, part tags (the homepage's parts, a chapter's part, the playlist's part
   headings) and the "part complete" note. */
[data-part="business"] { --part-fill: var(--scarlet); --part-on: var(--on-scarlet); --part-text: var(--scarlet-text); }
[data-part="investing"] { --part-fill: var(--emerald); --part-on: var(--on-emerald); --part-text: var(--emerald-text); }
[data-part="political"] { --part-fill: var(--amethyst); --part-on: var(--on-amethyst); --part-text: var(--amethyst-text); }
.part-tag, .part[data-part] .part__meta, .chapter-context__part, .blueprint-playlist-group[data-part] span {
  display: inline-block; padding: 0.42em 0.62em 0.36em; background: var(--part-fill); color: var(--part-on);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.1em; line-height: 1.2; text-transform: uppercase; font-variant-numeric: tabular-nums;
  text-decoration: none; white-space: nowrap;
}
/* The dark reading mode: the -text tokens take their light values; a tag there is the light value with ink on it. */
.reading-theme-dark .article-page {
  --blue-text: #9aa8ff; --blue-soft: #2a3160; --focus: #9aa8ff;
  --scarlet-text: #f87f73; --scarlet-soft: #4b1e1a; --emerald-text: #46b68c; --emerald-soft: #0c3627; --amethyst-text: #c78aeb; --amethyst-soft: #392247;
}
.reading-theme-dark .article-page [data-part] { --part-fill: var(--part-text); --part-on: #0b0e18; }

html.v2 { background: var(--ink); }
.v2-body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sc-font-text);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
.v2-body ::selection { background: var(--blue); color: #fff; }
.v2-body :focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
[data-ground="blue"] :focus-visible, [data-ground="ink"] :focus-visible, .index :focus-visible { outline-color: #fff; }
.v2-body cite { font-style: normal; white-space: nowrap; }      /* "The Blueprint" never breaks across lines */
.v2-body h1, .v2-body h2, .v2-body h3 { font-family: var(--sc-font-display); text-wrap: balance; }
.v2-body p { text-wrap: pretty; }

.skip {
  position: fixed; left: var(--g); top: 12px; z-index: 100;
  padding: 10px 14px; background: #fff; color: var(--ink); font-weight: 700;
  transform: translateY(-160%); transition: transform 0.16s var(--ease);
}
.skip:focus { transform: none; }

/* ---------------------------------------------------------------- controls */
.btn {
  display: inline-flex; align-items: center; gap: 0.75em;
  min-height: 54px; padding: 0 1.35em;
  font: 700 1rem/1 var(--sc-font-text); letter-spacing: -0.005em;
  text-decoration: none; white-space: nowrap;
  border: 0; border-radius: 0; cursor: pointer;
  transition: background-color 0.16s var(--ease), color 0.16s var(--ease), transform 0.12s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn .arrow { width: 1.05em; height: 1.05em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; transition: transform 0.16s var(--ease); }
.btn--light { background: #fff; color: var(--blue); }
.btn--blue { background: var(--blue); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  .btn--light:hover { background: var(--ink); color: #fff; }
  .btn--blue:hover { background: var(--ink); }
  .btn:hover .arrow { transform: translateX(3px); }
}
.link {
  color: inherit; font-weight: 700;
  text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 0.28em;
  transition: color 0.16s var(--ease), text-decoration-color 0.16s var(--ease);
}
.link:hover { color: var(--blue); }
.link--light:hover { color: var(--on-blue-soft); }

/* ------------------------------------------------------------ corner chrome */
.corner {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; justify-content: space-between; align-items: center;
  height: var(--corner-h); padding: 0 var(--g);
  color: #fff; pointer-events: none;
  transition: color 0.2s var(--ease);
}
/* Each control carries the ground it floats over, so text scrolling beneath never collides with it. */
.corner { --corner-bg: var(--blue); }
.corner--dark { color: var(--ink); --corner-bg: var(--paper); }
.corner--ink { --corner-bg: var(--el-bg); }
.corner > * { pointer-events: auto; }
.corner__name {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.7rem; margin-left: -0.7rem;
  background: var(--corner-bg); font-weight: 800; font-size: 1.05rem; letter-spacing: -0.02em; color: inherit; text-decoration: none;
}
/* The button never changes size: its outlined box is drawn behind the lines and the word (::before),
   so folding and unfolding it animates only opacity and position, which the compositor does alone
   (no layout while the page starts to scroll). --label-w fits "Close", the longer word. */
.corner__index {
  --label-w: 2.7em;
  position: relative; isolation: isolate; overflow: hidden;       /* the word slides in through the box's edge */
  display: inline-flex; align-items: center; gap: 0.7rem;
  min-height: 45px; padding: 0 calc(0.95rem + 1.5px);
  font: 700 0.95rem/1 var(--sc-font-text); color: inherit;
  background: none; border: 0; border-radius: 0; cursor: pointer;
  transition: color 0.16s var(--ease);
}
.corner__index::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--corner-bg); border: 1.5px solid currentColor;
  transition: opacity 0.3s var(--ease), background-color 0.16s var(--ease), border-color 0.16s var(--ease);
}
.corner__label { display: inline-block; width: var(--label-w); white-space: nowrap; transition: opacity 0.3s var(--ease), transform 0.42s var(--ease); }
/* At the very top the control is only its two lines, where they sit inside the button (the button,
   not the lines, keeps the page's right edge, as on the rest of the site). The first scroll fades in
   the outlined box while the lines step left and the word slides in behind them through the box's
   right edge. Hover or focus unfolds it too. */
html.at-top .corner__index:not(:hover):not(:focus-visible)::before, .corner.is-top .corner__index:not(:hover):not(:focus-visible)::before,
html.at-top .corner__index:not(:hover):not(:focus-visible) .corner__label, .corner.is-top .corner__index:not(:hover):not(:focus-visible) .corner__label { opacity: 0; }
html.at-top .corner__index:not(:hover):not(:focus-visible) :is(.corner__glyph, .corner__label), .corner.is-top .corner__index:not(:hover):not(:focus-visible) :is(.corner__glyph, .corner__label) { transform: translateX(calc(var(--label-w) + 0.7rem)); }
/* Two identical lines: 2 px each, 8 px apart top to top, a whole number of device pixels at every
   common density, so both always land on the same sub-pixel phase and draw the same. */
.corner__glyph { display: grid; gap: 6px; width: 18px; transition: transform 0.42s var(--ease); }
.corner__glyph i { display: block; height: 2px; background: currentColor; transition: transform 0.2s var(--ease); }
.corner__index[aria-expanded="true"] .corner__glyph i:first-child { transform: translateY(4px) rotate(45deg); }
.corner__index[aria-expanded="true"] .corner__glyph i:last-child { transform: translateY(-4px) rotate(-45deg); }
@media (hover: hover) and (pointer: fine) {
  .corner__index:hover { color: var(--blue); }
  .corner__index:hover::before { background: #fff; border-color: #fff; }
  .corner--dark .corner__index:hover { color: #fff; }
  .corner--dark .corner__index:hover::before { background: var(--ink); border-color: var(--ink); }
  html.at-top .corner--dark .corner__index:hover, .corner--dark.is-top .corner__index:hover { color: var(--ink); }
  html.at-top .corner--dark .corner__index:hover::before, .corner--dark.is-top .corner__index:hover::before { background: var(--corner-bg); border-color: currentColor; }
}
/* The header itself stays transparent while the menu is open: Safari 26 tints its status bar from a
   fixed element at the top edge and kept a blue header's tint after the menu closed (v2.0.3). */
.index-open .corner { color: #fff; --corner-bg: var(--blue); }

/* Safari 26 colours its status bar and floating toolbar from the background-color of fixed elements
   at the screen's edges. When the only element left at an edge is transparent it keeps the last
   colour it found, so the menu's blue stayed in the bars after the menu closed (and it was read
   mid-fade, so it was pale). These two strips always hold a solid colour for it to read, set by the
   page script: the ground under each edge, or the menu's blue while it is open.
   Safari's rules (iOS 26, found by others and matching what Ian saw): it reads a fixed element's own
   background-color only if the element is at least 3 px tall, at least 80% wide and within 4 px of the
   top (3 px of the bottom); it counts elements that are fading (so the menu's fade-in read pale); and
   when nothing qualifies it keeps the last colour. 2.0.6 to 2.1.3 painted nothing and 2.1.4 painted
   one pixel, so neither counted, and the pale blue from the menu's fade stuck (v2.1.5). Now: 6 px at
   the top, under the status bar, and 12 px at the bottom, 8 of them below the screen (the known
   recipe), both solid and on top of everything; shown only on iOS, where Safari tints. The script
   re-inserts a strip when its colour changes, so Safari looks again even when nothing scrolls. */
.edge {
  display: none; position: fixed; left: 0; right: 0; z-index: 120;
  background-color: var(--paper); pointer-events: none;
}
.edge--top { top: 0; height: 6px; }
.edge--bottom { bottom: -8px; height: 12px; }
@supports (-webkit-touch-callout: none) { .edge { display: block; } }

/* The index: every destination, full screen. */
.index {
  position: fixed; inset: 0; z-index: 55;
  display: grid; align-content: center;
  padding: calc(var(--corner-h) + 2vh) var(--g) calc(6vh + env(safe-area-inset-bottom, 0px));
  background: var(--blue); color: #fff;
  overflow-y: auto; overscroll-behavior: contain;
  /* Safari 26 shows the page under its floating toolbar, below the fixed viewport's bottom edge: the
     blue continues past that edge (a shadow is not clipped by the menu's own scrolling), so no strip
     of the page shows under the menu. */
  box-shadow: 0 50vh 0 0 var(--blue);
}
.index[hidden] { display: none; }
.index__nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--g); }
.index__nav a {
  display: grid; gap: 0.2rem; padding: 1.1rem 0 1.2rem;
  border-top: 1.5px solid var(--rule-blue);
  color: #fff; text-decoration: none;
}
.index__nav span { font-weight: 800; font-size: clamp(1.8rem, 4.2vw, 4.4rem); line-height: 0.95; letter-spacing: -0.04em; }
.index__nav small { font-size: 0.95rem; color: var(--on-blue-soft); line-height: 1.35; }
/* Where the reader is: a dot after the current destination (site.js sets aria-current). */
.index__nav a[aria-current="page"] span::after {
  content: ""; display: inline-block; width: 0.25em; height: 0.25em; margin-left: 0.24em;
  border-radius: 50%; background: currentColor; vertical-align: 0.3em;
}
@media (hover: hover) and (pointer: fine) {
  .index__nav a:hover span { text-decoration: underline; text-decoration-thickness: 0.06em; text-underline-offset: 0.12em; }
}
/* The panel is solid from its first frame (Safari reads its colour for the bars; a fading panel read
   pale); only the links fade in. */
.index-open .index__nav { animation: index-in 0.28s var(--ease) both; }
@keyframes index-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.index-open { overflow: hidden; }

/* ----------------------------------------------------------------- footer */
/* The site's footer (partials/v2-footer.hbs, on every page since 2.1.0): the name and the
   copyright line share the page gutter, and the icons' glyphs line up with the right edge. */
.site-footer { position: relative; z-index: 1; background: #121212; color: #fff; padding: 44px var(--g) 22px; }
.site-footer__top { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding-bottom: 30px; }
.site-footer__name {
  display: inline-flex; align-items: center; min-height: 44px;
  font-weight: 700; font-size: 22px; line-height: 1.2; letter-spacing: -0.02em; color: #fff; text-decoration: none;
}
.site-footer__social { display: flex; align-items: center; gap: 12px; list-style: none; margin: 0 -10px 0 0; padding: 0; }
.site-footer__social a {
  display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; color: #fff;
  transition: color 240ms ease, transform 280ms var(--ease);
}
.social-icon { display: block; width: 24px; height: 24px; background: currentColor; }
.social-icon--mail {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 4H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2Zm0 4-8 5-8-5V6l8 5 8-5v2Z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 4H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2Zm0 4-8 5-8-5V6l8 5 8-5v2Z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
}
.social-icon--instagram {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='3' y='3' width='18' height='18' rx='5' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='4' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='17.5' cy='6.5' r='1.25' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='3' y='3' width='18' height='18' rx='5' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='4' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='17.5' cy='6.5' r='1.25' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
}
.social-icon--substack {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 3h18v2.4H3V3Zm0 4.1h18v2.4H3V7.1Zm0 4.1h18v2.4H3v-2.4Zm2 4.1h14V21l-7-3.8L5 21v-5.7Z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 3h18v2.4H3V3Zm0 4.1h18v2.4H3V7.1Zm0 4.1h18v2.4H3v-2.4Zm2 4.1h14V21l-7-3.8L5 21v-5.7Z' fill='black'/%3E%3C/svg%3E") center / contain no-repeat;
}
@media (hover: hover) and (pointer: fine) {
  .site-footer__social a:hover { transform: translateY(-2px); }
  .site-footer__social a[aria-label="Email Ian"]:hover { color: #6f87ff; }
  .site-footer__social a[aria-label="Follow Ian on Instagram"]:hover .social-icon { background: linear-gradient(45deg, #f58529 0%, #dd2a7b 42%, #8134af 72%, #515bd4 100%); }
  .site-footer__social a[aria-label="Subscribe to Ian on Substack"]:hover { color: #ff6719; }
  .site-footer__bottom a:hover { color: #fff; }
}
.site-footer__bottom {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.25); padding-top: 16px;
  color: rgba(255, 255, 255, 0.64); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
}
.site-footer__bottom > span { justify-self: start; white-space: nowrap; }
.site-footer__bottom nav { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 28px; }
.site-footer__bottom a { display: inline-flex; align-items: center; min-height: 44px; color: inherit; text-decoration: none; transition: color 200ms ease; }
.site-footer__bottom > a { justify-self: end; gap: 7px; white-space: nowrap; }
.arrow-up {
  display: inline-block; width: 0.82em; height: 0.82em; background: currentColor; rotate: -90deg;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h12M9.25 3.25 14 8l-4.75 4.75' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 8h12M9.25 3.25 14 8l-4.75 4.75' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='square' stroke-linejoin='miter'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* Ghost's site-wide code injection still prints a legacy "All rights reserved" block after the page;
   the footer is the end of the page. */
body > .site-footer ~ .text-container { display: none !important; }
.site-footer a:focus-visible { outline: 2px solid #fff; outline-offset: 2px; border-radius: 4px; }
/* Tablet: the links take their own row before the three columns can collide. */
@media (min-width: 601px) and (max-width: 760px) {
  .site-footer__bottom { grid-template-columns: 1fr auto; gap: 8px 24px; }
  .site-footer__bottom nav { grid-column: 1 / -1; grid-row: 1; justify-content: flex-start; }
  .site-footer__bottom > span { grid-column: 1; grid-row: 2; }
  .site-footer__bottom > a { grid-column: 2; grid-row: 2; }
}
@media (max-width: 600px) {
  .site-footer { padding: 32px var(--g) 18px; }
  .site-footer__top { padding-bottom: 24px; gap: 16px; }
  .site-footer__name { font-size: 20px; }
  .site-footer__social { gap: 4px; }
  .site-footer__bottom { grid-template-columns: 1fr auto; grid-template-rows: auto auto; gap: 12px; }
  .site-footer__bottom nav { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 20px; grid-column: 1 / -1; grid-row: 1; }
  .site-footer__bottom > span { grid-column: 1; grid-row: 2; }
  .site-footer__bottom > a { grid-column: 2; grid-row: 2; }
}
@media (max-width: 360px) {
  .site-footer__top { flex-direction: column; align-items: flex-start; gap: 12px; }
  .site-footer__social { margin: 0 0 0 -10px; }
}

/* ------------------------------------------------------------------ phone */
@media (max-width: 860px) {
  /* Phones: all eight destinations fit above Safari's toolbar (the screen less its bars: 654 px tall
     on an iPhone 16 Pro, about 550 on an SE); type and spacing scale with that height, and the menu
     still scrolls on anything shorter. */
  .index { align-content: start; padding-top: calc(var(--corner-h) + 0.3rem); padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px)); }
  .index__nav { grid-template-columns: minmax(0, 1fr); }
  .index__nav a { padding: clamp(0.5rem, 1.5vh, 0.8rem) 0 clamp(0.55rem, 1.65vh, 0.9rem); padding: clamp(0.5rem, 1.5svh, 0.8rem) 0 clamp(0.55rem, 1.65svh, 0.9rem); }
  .index__nav span { font-size: clamp(1.45rem, min(8vw, 4.4vh), 2.6rem); font-size: clamp(1.45rem, min(8vw, 4.4svh), 2.6rem); }
  .index__nav small { font-size: 0.875rem; line-height: 1.3; }
}
@media (max-width: 420px) {
  .btn { padding: 0 1.1em; }
}

/* ---------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  .corner__index, .corner__index::before, .corner__label, .corner__glyph { transition: none; }
  .index-open .index__nav { animation: none; }
}

/* ------------------------------------------------------------ without JS */
html:not(.js) .corner__index { display: none; }
