/* ============================================================
   HECTOR CUEVAS · Leadership · Career · Finances
   Shared design system, multi-page static build.

   Palette is structural: navy owns panels and CTAs; gold is rare
   and earned. Editorial section numerals throughout.

   Theming: every surface, text and border colour resolves through
   a token below, so the dark theme is a token swap rather than a
   parallel stylesheet. Components should never hardcode a colour.

   Grid tracks: every flexible track in this file is written
   `minmax(0, 1fr)`, never a bare `1fr`. This is a house rule, not a
   preference. A bare `1fr` means `minmax(auto, 1fr)`, and that `auto`
   floor is the min-content width of whatever lands in the cell: one
   unwrappable child (a nowrap button, a long pill, a URL) silently
   widens the column, then the grid, then the page, and the reader
   gets a sideways scrollbar on a phone. Writing the zero says the
   track may be as narrow as the layout needs and its contents will
   cope. It cost this site two separate horizontal-overflow bugs
   before it was written down.

   Shrink-to-fit: a box that should hug its text but never outgrow
   its container is `width: fit-content`, never `width: max-content`
   with a percentage `max-width` beside it. The percentage resolves
   to `auto` while the browser is working out intrinsic sizes, so it
   holds nothing back at the only moment it was there to help; the
   box contributes its full one-line width to the track floor above
   and the same overflow follows.
   ============================================================ */

/* ============================================================
   TYPE · self-hosted, variable, latin subset
   Three variable fonts, ~170 KB total, served from this origin.
   Self-hosting removes a render-blocking third-party request and a
   DNS round trip on first paint, and means no visitor's IP is handed
   to a font CDN just for reading about their budget.
   Licensed under the SIL Open Font License; see assets/fonts/.
   ============================================================ */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/fraunces-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/fraunces-var-italic.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("fonts/jetbrains-var.woff2") format("woff2-variations");
}

/* Metric-matched fallbacks. While the webfont is still in flight the
   page renders in a system face scaled to Inter's proportions, so the
   swap does not shove the layout around. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Helvetica Neue"), local("Arial"), local("Liberation Sans");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22.4%;
  line-gap-override: 0%;
}

:root {
  color-scheme: light;

  /* ---- Brand constants (identical in both themes) ---- */
  --brand-navy: #0a1f3e;
  --brand-gold: #c9a961;

  /* ---- Surfaces ---- */
  --bg: #fffdf9;             /* page canvas */
  --card: #ffffff;           /* raised card / panel fill */
  --paper: #faf7f1;          /* warm off-white for section banding */
  --surface: #f3efe7;        /* slightly stronger surface tone */
  --rule: #e8e3d8;           /* hairline rules */

  /* ---- Text ---- */
  --ink: #141414;            /* body text */
  --ink-soft: #2a2a2a;       /* secondary heads */
  --mid: #5d646f;            /* captions, meta */
  --ink-accent: #0a1f3e;     /* navy acting as TEXT (headings, inline links) */

  /* ---- Navy family (panels, CTAs, logotype) ---- */
  --navy: #0a1f3e;
  --navy-2: #0d2547;
  --navy-glow: rgba(10,31,62,0.08);
  --on-navy: #eef1f6;        /* body text sitting on a navy panel */
  --on-navy-strong: #ffffff; /* headings on a navy panel */

  /* Navy has a third job, and it is the one that breaks. As a SURFACE it holds
     white text and only has to be dark. As TEXT it is --ink-accent. But in a
     stacked bar or a legend dot it is DATA: a shape whose whole purpose is to
     be told apart from the panel behind it.

     In the light theme all three can be the same navy. In the dark theme they
     cannot: a #14263f bar on a #131c28 panel is 1.14:1, which is not a bar,
     it is a gap. The bills segment of the budget breakdown and the
     contributions slice of the retirement projection are usually the largest
     figures on those pages, and both were invisible after dark.

     Same split as --ink-accent and --gold-ink: name the role, let the theme
     answer. Any chart added later asks for this and is right on both fields. */
  --navy-data: #0a1f3e;      /* navy acting as a DATA fill (bars, legend dots) */

  /* ---- Gold family ----
     Three jobs, and they are not interchangeable. --gold is the accent as a
     SURFACE: fills, rules, borders, and lettering sitting on a navy panel,
     where it clears 7:1 and looks like money. --gold-ink is the same accent
     acting as TEXT on a light field, where the bright gold reads at 2.2:1 on cream,
     which is decoration pretending to be a word, so this is darkened until an
     eyebrow at 11px is genuinely legible. --gold-deep goes back to the single
     job its name describes: the hover state. Same idea as --ink-accent, which
     already separates navy-as-text from navy-as-surface. */
  --gold: #c9a961;
  --gold-soft: #e9dcb6;      /* gold tints for chips */
  --gold-ink: #8c6420;       /* the accent acting as TEXT on a light field */
  --on-gold-soft: #5a4515;   /* text sitting on a --gold-soft chip */
  --gold-deep: #a8884a;      /* the dark stop of the gold gradient */

  /* ---- Focus ----
     A focus ring is not text and not decoration. It is the only thing
     telling a keyboard user where they are, which is why WCAG holds it to
     3:1 against whatever it is drawn on rather than leaving it to taste.
     The brand gold measures 2.25:1 on white. It looked deliberate, it
     matched everything, and it was under the line on every light page on
     the site, and a ring you have to hunt for is the same as no ring.

     So gold gets the treatment navy and gold-as-text already got: name
     the role, let the theme answer. On a light field this is the deeper
     gold (5.3:1 on white, 4.7:1 on cream), still unmistakably the brand,
     now actually a boundary. On a dark field the bright gold IS the
     visible one at 9.2:1, so there is nothing to correct. And on a navy
     panel the dark-fields block below re-answers it, because a panel that
     inverts everything else has no business keeping a light-field ring. */
  --focus-ring: #8c6420;
  --focus-halo: rgba(140,100,32,0.20);

  /* ---- Data marks ----
     A legend dot or a bar segment is a graphical object under the same
     3:1 rule, and the brand gold fails it as a fill for exactly the
     reason it failed as a ring. Darkening the gold was the obvious move
     and the wrong one: it would have dropped gold-against-green in the
     stacked bar from 2.2:1 to 1.3:1, fixing the mark against the panel by
     making it vanish into its own neighbour.

     A boundary is the fix the spec actually names. One hairline, dark on
     light and light on dark, both clearing 3:1 against the panel, gives
     every mark a defined edge whatever colour fills it, including
     colours added years from now by someone who never read this. */
  --data-edge: rgba(10,31,62,0.55);

  /* ---- Semantic feedback ---- */
  --pos: #2f7d5b;
  --neg: #b03a2e;
  --warn: #a8720f;

  /* ---- Legacy alias (older rules still reference it) ---- */
  --white: #ffffff;

  /* ---- Elevation ---- */
  --shadow-1: 0 1px 2px rgba(10,31,62,0.05);
  --shadow-2: 0 12px 32px -14px rgba(10,31,62,0.20);
  --shadow-3: 0 26px 60px -28px rgba(10,31,62,0.34);

  /* ---- Type ---- */
  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --sans: "Inter", "Inter Fallback", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* ---- Rhythm ---- */
  --maxw: 1240px;
  --gutter: clamp(20px, 4vw, 56px);
  --section-y: clamp(72px, 9vw, 140px);
  --radius-sm: 4px;
  --radius: 8px;
  --radius-lg: 18px;

  /* ---- Motion ---- */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ============================================================
   DARK THEME
   Same structure, inverted field. Navy panels stay navy but lift
   above the page instead of dropping below it, so the editorial
   banding still reads. Gold brightens a step to hold contrast.
   ============================================================ */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0a1017;
  --card: #131c28;
  --paper: #0e1620;
  --surface: #121b26;
  --rule: #26313f;

  --ink: #e9eef5;
  --ink-soft: #c3cddb;
  --mid: #8d99a9;
  --ink-accent: #f0f5fb;

  --navy: #14263f;
  --navy-2: #1a2f4d;
  --navy-glow: rgba(0,0,0,0.5);
  --on-navy: #dfe7f1;
  --on-navy-strong: #ffffff;

  /* Navy-as-surface can stay dark here because that is its whole job.
     Navy-as-data cannot: #14263f on the #131c28 panel is 1.14:1, and the
     two places that used it (the bills segment of the budget bar and the
     contributions slice of the retirement projection) are routinely the
     largest figures on their pages. This is the same navy read off the
     other end of the ramp: 6.4:1 on the panel, and it still says navy. */
  --navy-data: #7ba1d4;

  --gold: #d9ba76;
  --gold-soft: #4a3c1e;
  /* On a dark field the bright gold IS the readable one, and it sits at 10:1 on
     the page canvas. So gold-ink and gold converge here, which is the point of
     having the token: the rule that uses it does not have to know the theme. */
  --gold-ink: #d9ba76;
  --on-gold-soft: #f0e4c4;
  --gold-deep: #c9a961;

  /* Same convergence, same reason: the bright gold is the one that reads
     on a dark field, so the focus ring is simply gold here. The hairline
     round a data mark flips, though, because a dark edge on a dark panel is not
     an edge. */
  --focus-ring: #d9ba76;
  --focus-halo: rgba(217,186,118,0.26);
  --data-edge: rgba(233,238,245,0.62);

  --pos: #4fb98a;
  --neg: #e0705f;
  --warn: #d6a03f;

  --white: #131c28;

  --shadow-1: 0 1px 2px rgba(0,0,0,0.4);
  --shadow-2: 0 12px 32px -14px rgba(0,0,0,0.7);
  --shadow-3: 0 26px 60px -28px rgba(0,0,0,0.9);
}

/* -----  reset-ish  ----- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
body {
  margin: 0;
  font-family: var(--sans);
  color: var(--ink);
  background: var(--bg);
  font-size: 16.5px;
  line-height: 1.55;
  font-feature-settings: "ss01","cv11";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 0.4s var(--ease), color 0.4s var(--ease);
}
img, svg { display: block; max-width: 100%; }
img { height: auto; }
button { font: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
input, select, textarea { font: inherit; color: inherit; }
:root { accent-color: var(--gold); }

/* Two-tone focus ring: a soft halo under a solid core. The core is the
   part that has to clear 3:1, so it reads --focus-ring rather than --gold
   directly; the halo is there to lift the core off a busy backdrop and is
   allowed to be quiet. Both are tokens so a dark panel can re-answer them
   in one place instead of every rule guessing where it landed.

   Written once, globally, and then left alone. Four tool pages each
   re-declared this ring in navy, which is 1.14:1 in the dark theme, the
   comment this replaces already promised the ring stayed visible there,
   and it had stopped being true. gfxcontrast.py now measures it. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 2px;
  box-shadow: 0 0 0 5px var(--focus-halo);
}

::selection { background: var(--navy); color: var(--gold-soft); }
:root[data-theme="dark"] ::selection { background: var(--gold); color: #0a1017; }

/* Long-form headings break at sensible points; body copy avoids
   orphans. Both degrade silently where unsupported. */
h1, h2, h3, .lead { text-wrap: balance; }
p, li { text-wrap: pretty; }

/* Consistent scrollbar treatment across themes (Firefox + WebKit). */
html { scrollbar-color: var(--rule) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--rule);
  border: 3px solid var(--bg);
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: var(--mid); }

/* -----  layout primitives  ----- */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
.section { padding: var(--section-y) 0; position: relative; }
.section--paper { background: var(--paper); }
.section--tight { padding: clamp(48px, 6vw, 88px) 0; }
.section--navy {
  background: var(--navy);
  color: var(--on-navy);
  position: relative;
  overflow: hidden;
}

/* ============================================================
   DARK FIELDS

   A navy panel sitting inside a light page is that page's opposite,
   and the way to handle it is not to write one more
   `.section--navy .whatever { color: white }` rule every time
   something new lands inside one. This file had fourteen of those,
   hard-coding six different whites between them, and four more were
   written as `style=` attributes in the markup because by then it was
   easier than finding the pattern.

   So a dark panel is treated as what it actually is: its own small
   theme. It swaps the same tokens a theme swaps, and every rule that
   already says `var(--ink-soft)` or `var(--rule)` gets the right
   answer without being told where it landed. A component dropped in
   here tomorrow is correct before anyone looks at it.

   One list, deliberately: it is the site's inventory of "this is a
   dark field", and the PRINT section at the bottom of this file reads
   the same names to decide what has to turn back into ink. Keeping it
   single is what stops the next dark panel from being fixed on screen
   and forgotten on paper.
   ============================================================ */
.section--navy, .ctaband, .hero__panel, .footer,
.toolnews, .about-portrait, .channel-tile,
.videocard__thumb, .toolcard__icon,
.award-feature__seal, .gear--drive .gear__badge, .on-dark, .on-navy {
  --ink: var(--on-navy-strong);
  --ink-soft: var(--on-navy);
  --ink-accent: var(--on-navy-strong);   /* navy-as-text has no job on navy */
  --mid: rgba(255, 255, 255, 0.62);
  --rule: rgba(255, 255, 255, 0.14);
  --card: rgba(255, 255, 255, 0.06);     /* a raised chip, not a white one */
  --gold-ink: var(--gold);
  --on-gold-soft: var(--gold);
  --focus-ring: var(--gold);              /* the light-field ring is too dark here */
  --focus-halo: rgba(201,169,97,0.30);
  --data-edge: rgba(255,255,255,0.62);
}

/* Two things do not simply invert. An eyebrow goes gold rather than
   white, because white would compete with the headline directly under
   it, and a link has to stay visibly a link, which on a dark field
   means the accent, not the body colour. */
.section--navy .eyebrow, .ctaband .eyebrow, .hero__panel .eyebrow, .toolnews .eyebrow,
.on-dark .eyebrow,
.section--navy a.linky, .on-dark a.linky { color: var(--gold-ink); }

/* -----  type system  ----- */
h1, h2, h3, h4 {
  font-family: var(--display);
  color: var(--ink);
  margin: 0 0 0.4em;
  letter-spacing: -0.01em;
  font-weight: 500;
  line-height: 1.05;
}
h1 {
  font-size: clamp(44px, 7.2vw, 96px);
  line-height: 0.98;
  letter-spacing: -0.025em;
  font-weight: 500;
}
h2 {
  font-size: clamp(32px, 4.4vw, 56px);
  line-height: 1.02;
  letter-spacing: -0.02em;
}
h3 { font-size: clamp(22px, 2.2vw, 28px); }
h4 { font-size: 18px; letter-spacing: -0.005em; font-weight: 600; }
/* One name for emphasis, and it works wherever it is written.

   There were two: `.italic`, which was a plain utility and always did what it
   said, and `.em`, which was the editorial treatment, italic, navy, and a
   gold bar under it in a hero. `.em` was only ever declared inside `.hero h1`,
   `.page-hero h1`, `.ctaband` and `.prose p`, so writing it in an ordinary
   section heading matched nothing and rendered as plain text. Five headings
   across four pages were doing exactly that, including "Get Field Notes in
   your inbox" on the contact page, and nothing catches it: the class is real,
   the markup is valid, and the page merely looks a little flatter than it was
   meant to.

   So the italic lives at the root now and the context adds the colour. A base
   rule cannot be out of scope, which means this particular mistake has stopped
   being possible rather than merely stopped happening. */
.em { font-style: italic; }
p { margin: 0 0 1em; }
.lead {
  font-size: clamp(18px, 1.55vw, 22px);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 60ch;
}
.muted { color: var(--mid); }

/* The line under a headline that tells you what the thing is, a book's
   subtitle, a section's promise. It takes the accent rather than naming a
   colour, so the same class is a darkened gold on cream and a bright gold
   on navy without a second rule being written for it. */
.deck {
  font-family: var(--display);
  font-style: italic;
  font-size: clamp(18px, 1.8vw, 22px);
  line-height: 1.35;
  color: var(--gold-ink);
  max-width: 40ch;
  margin: 0 0 20px;
}

/* Editorial section number + label (e.g. "01 / SERVICES") */
.eyebrow {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-accent);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 28px;
}
.eyebrow::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}
.eyebrow .num { color: var(--gold-ink); font-weight: 500; }
/* small caption */
.caption {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
}

/* ----- buttons ----- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 15.5px;
  letter-spacing: -0.005em;
  border: 1px solid transparent;
  transition: transform 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
  white-space: nowrap;
}
.btn--primary {
  background: var(--navy);
  color: #fff;
  border-color: var(--ink-accent);
}
.btn--primary:hover { background: var(--navy-2); transform: translateY(-1px); box-shadow: 0 8px 24px -10px var(--navy-glow); }
.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--rule);
}
.btn--ghost:hover { border-color: var(--ink); transform: translateY(-1px); }.btn--light {
  background: #fff;
  color: var(--navy);
  border-color: #fff;
}
.btn--light:hover { transform: translateY(-1px); box-shadow: 0 12px 30px -16px rgba(0,0,0,0.5); }
.btn--outline-light {
  background: transparent;
  color: #fff;
  border-color: rgba(255,255,255,0.4);
}
.btn--outline-light:hover { border-color: #fff; transform: translateY(-1px); }
.btn .arrow {
  display: inline-block;
  transition: transform 0.3s var(--ease);
}
.btn:hover .arrow { transform: translateX(3px); }

/* in-body link with gold underline animation */
.linky {
  position: relative;
  display: inline-block;
  font-weight: 500;
  padding-bottom: 2px;
  color: inherit;
}
.linky::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--gold);
  transform-origin: left center;
  transform: scaleX(0.35);
  transition: transform 0.45s var(--ease);
}
.linky:hover::after { transform: scaleX(1); }

/* ============================================================
   SCROLL PROGRESS BAR
   ============================================================ */
.progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, var(--gold), var(--gold-deep));
  z-index: 80;
  pointer-events: none;
}

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,253,249,0.85);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.nav.is-scrolled { border-bottom-color: var(--rule); background: rgba(255,253,249,0.94); box-shadow: 0 12px 32px -26px rgba(10,31,62,0.45); }
/* padding-block, not the `padding: 18px 0` shorthand. `.nav__inner` is a
   `.wrap`, and `.wrap` owns the page's inline gutter, one declaration, one
   place. The shorthand writes both axes, so the `0` silently replaced
   `var(--gutter)` and pulled the brand and the call to action out to the
   window edges: at 1440 the mark sat 56px left of every headline on the page.
   Restating the gutter here would fix the symptom and keep the trap; writing
   only the axis this rule actually cares about removes it. */
.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 18px;
  gap: 24px;
}
.logotype {
  font-family: var(--display);
  font-weight: 500;
  font-size: 18px;
  line-height: 1;
  color: var(--ink-accent);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  letter-spacing: -0.01em;
}
.logotype .mark {
  width: 26px; height: 26px;
  border-radius: 6px;
  background: var(--navy);
  display: inline-grid;
  place-items: center;
  position: relative;
  flex-shrink: 0;
}
.logotype .mark::before, .logotype .mark::after {
  content: "";
  position: absolute;
  background: var(--gold);
}
.logotype .mark::before { width: 10px; height: 1.5px; top: 12px; left: 8px; }
.logotype .mark::after  { width: 1.5px; height: 10px; top: 8px;  left: 12px; }
/* 0.16em, not the 0.22em this was set at. Tracking is the only dimension of
   this line that is free to move: the words are the site's positioning and
   the size is 11px because that is already the floor for a line meant to be
   read. At 0.22em with spaced separators the line measured 320px, which is
   wider than the footer column it lives in at every viewport under 1200 and
   wider than a 320px phone can hold at all, so it broke, and a three-part
   tagline that breaks after a separator reads as two half-finished thoughts.
   At 0.16em with the separators unspaced it measures 228px, still plainly a
   tracked-out lockup line, and it survives a 320px viewport with room over.
   The separators are unspaced in build.py, where the reason is written down;
   the two changes are one decision and neither works alone. */
.logotype small {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mid);
  margin-top: 3px;
}
.logotype .stack { display: flex; flex-direction: column; line-height: 1; }

.nav__links {
  display: flex;
  align-items: center;
  gap: 6px;
}
.nav__links a {
  position: relative;
  font-size: 15px;
  font-weight: 500;
  padding: 10px 14px;
  border-radius: 6px;
  color: var(--ink-soft);
  transition: color 0.2s var(--ease);
}
.nav__links a:hover { color: var(--ink-accent); }
.nav__links a[aria-current="page"] { color: var(--ink-accent); }
.nav__links a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 14px; right: 14px;
  bottom: 4px;
  height: 1.5px;
  background: var(--gold);
}
.nav__cta { display: inline-flex; align-items: center; gap: 10px; }
.nav__cta .btn { padding: 10px 16px; font-size: 14px; }

.nav__burger {
  display: none;
  background: transparent;
  border: 1px solid var(--rule);
  width: 42px;
  height: 38px;
  border-radius: 8px;
  padding: 0;
  align-items: center;
  justify-content: center;
}
.nav__burger__bars {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--navy);
  position: relative;
  flex-shrink: 0;
}
.nav__burger__bars::before,
.nav__burger__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 1.5px;
  background: var(--navy);
}
.nav__burger__bars::before { top: -6px; }
.nav__burger__bars::after { top: 6px; }
/* Shown only in the phone treatment below, where there is room for it. */
.nav__burger__label {
  display: none;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-accent);
}

/* 1080, not the 940 this sat at, and the old number was never right; it was
   only wrong at widths nobody had opened the site at. The header row wants a
   159px lockup, 452px of primary links, 285px of controls and two 24px gaps,
   so 944px of content, and `.wrap` hands back the viewport less two
   `--gutter`s, which is 8% of it until the gutter caps at 56. 944px of content
   therefore needs about a 1026px viewport. Between 941 and 1026 the flex line
   had nowhere to take the difference from except the brand, and it took it:
   at 990 the lockup was squeezed to its 130px min-content floor, the wordmark
   broke across lines, and the sticky header stood 120px tall on every page,
   which is a sixth of the screen a small laptop has.
   1080 rather than 1030 for the same reason the phone block below is 640
   rather than 517: at 1030 the row cleared by single digits, and single digits
   are luck rather than a decision. At 1081 it clears by 51. */
@media (max-width: 1080px) {
  .nav__links { display: none; }
  .nav__cta .btn--ghost { display: none; }
  /* The menu control says what it does and clears a 44px touch target, which
     a bare 42x38 hamburger did neither of. It is styled here rather than in
     the phone block below so that the control has one appearance everywhere
     it is shown, and the 640px breakpoint is left to change the composition
     around it rather than the control itself. The accessible name stays
     "Open menu" and contains the visible "Menu", satisfying WCAG 2.5.3
     Label in Name. */
  .nav__burger { display: inline-flex; width: auto; height: 44px; padding: 0 14px; gap: 9px; }
  .nav__burger__label { display: block; }
}

/* The phone header is a different composition, not a squeezed desktop one.

   Measured here, at the sizes the header is built from today: the lockup
   (mark and wordmark, one line) is 159px, the controls with the gold button
   in them 292px, and the gap between them 24px. That is 475px of content, and
   content is the viewport less two `--gutter`s, so it wants roughly a 517px
   viewport. Below that the flex line has nowhere to take the difference from
   except the brand, and it takes it: the wordmark breaks, and a sticky header
   that grows is a header that eats a phone screen for the whole session.
   320 matters more than its share here because it is not a museum piece; it
   is also a 375px phone at 117% text zoom, and a line that overflows a 320px
   viewport is a WCAG 1.4.10 reflow failure rather than an ugly one.

   So on phones the header carries the brand and the way in, and nothing else.
   The gold call to action does not disappear with it: the sheet opens with a
   full-width copy of the same button, the hero carries one above the fold,
   and every page closes with the band and the footer form.

   640 rather than the measured 517, deliberately, because a breakpoint set
   where the arithmetic stops working has no room for the arithmetic to be
   slightly wrong. At 641 the wide composition clears by 115px and at 640 the
   phone one starts with 323px spare; at 320, the tightest case on the site,
   the phone header still clears by 14. That margin was checked against a real
   worst case rather than an imagined one: with the webfonts blocked outright
   the fallback stack measures narrower here, not wider, so every figure above
   improves rather than degrades. And if some other fallback did run wide,
   `.logotype` shrinks before the flex line can overflow, so the failure is a
   wrapped wordmark and not a horizontal scrollbar, the degradation this
   stylesheet prefers, for the same reason the award pill below refuses
   nowrap. lockup.py is what notices if it ever comes to that. */
@media (max-width: 640px) {
  .nav__cta .btn--primary { display: none; }
  .nav__inner { gap: 16px; }
}

/* mobile sheet */
.mobile-sheet {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--white);
  display: none;
  flex-direction: column;
  padding: 24px var(--gutter);
}
.mobile-sheet.is-open { display: flex; }
.mobile-sheet__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 28px;
}
.mobile-sheet nav { display: flex; flex-direction: column; }
.mobile-sheet a {
  font-family: var(--display);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.02em;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-accent);
}
.mobile-sheet a[aria-current="page"] { color: var(--gold-ink); }
.mobile-sheet__cta { margin-top: 28px; display: flex; flex-direction: column; gap: 12px; }
.mobile-sheet__cta .btn { width: 100%; justify-content: center; }
.mobile-sheet .close {
  background: transparent;
  border: 1px solid var(--rule);
  width: 40px; height: 40px;
  border-radius: 50%;
  color: var(--ink-accent);
  font-size: 22px;
  line-height: 1;
}

/* ============================================================
   HERO (home)
   ============================================================ */
.hero {
  padding-top: clamp(40px, 6vw, 80px);
  padding-bottom: clamp(60px, 8vw, 120px);
  position: relative;
  overflow: hidden;
}
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 80px);
  align-items: end;
}
@media (max-width: 920px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: 56px; }
}
.hero__intro {
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.hero__intro .eyebrow { margin-bottom: 0; }
/* The gold highlight under the italic phrase in a hero headline. Used on the
   home page and, identically, on every inner-page hero, one rule rather than
   two, because the two had already been written twice and would eventually
   have been edited once.

   It is a background gradient on an inline box, not an absolutely positioned
   ::after on an inline-block, and the difference is not stylistic. An
   inline-block is atomic: the moment its text needs a second line it claims
   the full available width, and two things follow from that on the home page
   at 1280px and up. The sentence's full stop had nowhere to sit beside a box
   as wide as the column, so it printed alone on a line of its own under the
   headline, a single black dot, on the first screen of the site, which every
   check in this harness passed because a period is legitimate text in a
   legitimate place. And the rule itself, drawn to the box rather than to the
   words, ran some two hundred and ninety pixels past the end of "English",
   reading as a deliberate swash at 1440px and as a snug underline at 1180px
   where the phrase happened to fit on one line.

   A background wraps the way text wraps, because it is on text: each line
   fragment gets its own bar (box-decoration-break: clone), punctuation stays
   in the sentence, and the paint sits behind the glyphs without needing
   z-index: -1 to get there, which was the other quiet hazard, since a
   negative index escapes to the nearest stacking context and had only ever
   worked here by the accident of what that context was. */
.hero h1 .em,
.page-hero h1 .em {
  color: var(--ink-accent);
  background-image: linear-gradient(var(--gold-soft), var(--gold-soft));
  background-repeat: no-repeat;
  /* Inset 4px each side, 6px tall, sitting 4px above the text's own bottom.
     The vertical calc reads oddly and is exact: with a percentage plus a
     length, the browser resolves position as (box − image) × pct + length,
     so `100% − 10px` puts the bottom of a 6px bar 4px up from the box. */
  background-size: calc(100% - 8px) 6px;
  background-position: 4px calc(100% - 10px);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hero__sub {
  max-width: 56ch;
  font-size: clamp(17px, 1.4vw, 21px);
  color: var(--ink-soft);
  line-height: 1.45;
}
.hero__ctas {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.hero__panel {
  position: relative;
  background: var(--navy);
  color: var(--on-navy);
  border-radius: var(--radius-lg);
  padding: 36px;
  min-height: 380px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  isolation: isolate;
}
.hero__panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 100% 0%, rgba(201,169,97,0.18), transparent 55%),
    radial-gradient(80% 60% at 0% 100%, rgba(255,255,255,0.06), transparent 60%);
  z-index: -1;
}
.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(201,169,97,0.45);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  width: fit-content;
}
/* The badge is 213px of tracking-heavy monospace in a panel that has 208px of
   room once its padding is paid for, on a 320px screen. Five pixels short is
   still short: it wrapped, and it wrapped in the one place it must not, with
   the separator opening the second line as "· 2026". Tightening the letter
   spacing and two pixels of padding buys the twenty it needs.

   420px is this file's one narrow-phone breakpoint; the award pill uses it
   too. It is wider than either rule strictly needs, the badge only runs out
   of room at 320, because a chip that quietly changes size somewhere between
   two phones looks like a bug, and holding one setting across every handset
   costs nothing. */
@media (max-width: 420px) {
  .hero__badge { letter-spacing: 0.1em; padding: 6px 10px; }
}
.hero__badge .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 3px rgba(201,169,97,0.2);
}
.hero__panel h2 {
  font-size: clamp(24px, 2.4vw, 32px);
  color: var(--ink);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 28px 0 10px;
  font-weight: 500;
}
.hero__panel p { color: rgba(255,255,255,0.78); margin: 0; font-size: 16px; }
.hero__panel .meta {
  margin-top: 28px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  border-top: 1px solid rgba(255,255,255,0.12);
  padding-top: 18px;
}
.hero__panel .meta div span:first-child {
  display: block;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
  margin-bottom: 4px;
}
.hero__panel .meta div span:last-child {
  color: #fff;
  font-size: 15px;
  font-weight: 500;
}

/* ============================================================
   STATS BAND (animated counters)
   ============================================================ */
.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.stats > div {
  padding: clamp(24px, 3vw, 38px) 24px;
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.stats > div:last-child { border-right: 0; }
.stats .v {
  font-family: var(--display);
  font-size: clamp(34px, 4vw, 52px);
  color: var(--ink-accent);
  letter-spacing: -0.02em;
  line-height: 1;
  font-weight: 500;
}.stats .k {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
}
@media (max-width: 760px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats > div:nth-child(2) { border-right: 0; }
  .stats > div:nth-child(1), .stats > div:nth-child(2) { border-bottom: 1px solid var(--rule); }
}

/* compact at-a-glance strip (home hero) */
.hero__strip {
  margin-top: clamp(48px, 7vw, 100px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.hero__strip > div {
  padding: 20px 24px;
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hero__strip > div:last-child { border-right: 0; }
.hero__strip .k {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
}
.hero__strip .v {
  font-family: var(--display);
  font-size: 22px;
  color: var(--ink-accent);
  letter-spacing: -0.01em;
}
@media (max-width: 760px) {
  .hero__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero__strip > div:nth-child(2) { border-right: 0; }
  .hero__strip > div:nth-child(1), .hero__strip > div:nth-child(2) { border-bottom: 1px solid var(--rule); }
}

/* ============================================================
   PAGE HERO (inner pages)
   ============================================================ */
.page-hero {
  padding-top: clamp(48px, 6vw, 88px);
  padding-bottom: clamp(40px, 5vw, 72px);
  position: relative;
}
.page-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: end;
}
@media (max-width: 880px) { .page-hero__inner { grid-template-columns: minmax(0, 1fr); gap: 28px; } }
.page-hero h1 {
  font-size: clamp(40px, 6vw, 76px);
  margin: 0;
}
.page-hero h1 .em { color: var(--ink-accent); }
.page-hero .lead { margin: 0; }

/* Breadcrumb: an ordered list, because that is what it is. The separator
   is drawn in CSS so it never lands in the accessibility tree or in a
   copy-paste of the trail. */
.crumbs {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mid);
  margin-bottom: 26px;
}
.crumbs ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.crumbs li { display: flex; align-items: center; gap: 10px; }
.crumbs li + li::before {
  content: "/";
  color: var(--rule);
  font-size: 12.5px;
}
.crumbs a { color: var(--mid); transition: color 0.2s var(--ease); }
.crumbs a:hover { color: var(--ink-accent); }
.crumbs [aria-current="page"] { color: var(--gold-ink); }
.section__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: clamp(24px, 5vw, 80px);
  align-items: end;
  margin-bottom: 24px;
}
@media (max-width: 880px) {
  .section__head { grid-template-columns: minmax(0, 1fr); gap: 18px; }
}
.section__head h2 { margin: 0; }
.section__head .lead { margin: 0; }

/* ============================================================
   PRACTICE AREAS
   ============================================================ */
/* This is the grid that taught the file its `minmax(0, …)` rule: one pill
   reading "Co-facilitated with Hamilton Esteban, LMHC" pushed these cards to
   404px and gave the page a sideways scrollbar on every phone made. */
.practice__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 48px;
}
@media (max-width: 760px) { .practice__grid { grid-template-columns: minmax(0, 1fr); } }
.practice__card {
  background: var(--white);
  border: 1px solid var(--rule);
  padding: 32px;
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.practice__card:hover {
  transform: translateY(-2px);
  border-color: var(--ink-accent);
  box-shadow: 0 30px 60px -50px var(--navy-glow);
}
.practice__card .ix {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.practice__card h3 {
  font-size: 26px;
  color: var(--ink-accent);
  margin: 4px 0 0;
}
.practice__card p { color: var(--ink-soft); font-size: 16px; margin: 0; }/* ============================================================
   APPROACH · stepper
   ============================================================ */
.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin-top: 56px;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.step {
  padding: 28px 28px 32px;
  border-right: 1px solid var(--rule);
  position: relative;
}
.step:last-child { border-right: 0; }
.step .num {
  font-family: var(--display);
  font-size: 60px;
  color: var(--ink-accent);
  line-height: 0.9;
  letter-spacing: -0.03em;
  font-weight: 500;
}
.step h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 22px;
  color: var(--ink);
  margin: 16px 0 8px;
  letter-spacing: -0.01em;
}
.step p { color: var(--mid); font-size: 16px; margin: 0; }
.step .meta {
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
@media (max-width: 880px) {
  .steps { grid-template-columns: minmax(0, 1fr); }
  .step { border-right: 0; border-bottom: 1px solid var(--rule); }
  .step:last-child { border-bottom: 0; }
}
/* ============================================================
   RESOURCES teaser
   ============================================================ */
.resources {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 28px;
  align-items: center;
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: clamp(32px, 5vw, 56px);
  margin-top: 56px;
  background: var(--paper);
  position: relative;
  overflow: hidden;
}
.section--paper .resources { background: var(--card); }
@media (max-width: 760px) { .resources { grid-template-columns: minmax(0, 1fr); } }
.resources h3 {
  font-family: var(--display);
  font-size: clamp(28px, 3vw, 40px);
  color: var(--ink-accent);
  margin: 0 0 16px;
  letter-spacing: -0.02em;
  font-weight: 500;
}
.resources p { margin: 0; color: var(--ink-soft); max-width: 46ch; }
/* ============================================================
   FAQ ACCORDION
   ============================================================ */
.faq {
  margin-top: 48px;
  border-top: 1px solid var(--rule);
}
.faq__item { border-bottom: 1px solid var(--rule); }
.faq__q {
  width: 100%;
  background: transparent;
  border: 0;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 26px 4px;
  font-family: var(--display);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.2;
  transition: color 0.2s var(--ease);
}
.faq__q:hover { color: var(--ink-accent); }
.faq__icon {
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  position: relative;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.faq__icon::before, .faq__icon::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  background: var(--navy);
  transition: transform 0.35s var(--ease), background 0.3s var(--ease);
}
.faq__icon::before { width: 12px; height: 1.6px; transform: translate(-50%,-50%); }
.faq__icon::after  { width: 1.6px; height: 12px; transform: translate(-50%,-50%); }
.faq__q[aria-expanded="true"] .faq__icon { background: var(--navy); border-color: var(--ink-accent); }
.faq__q[aria-expanded="true"] .faq__icon::before,
.faq__q[aria-expanded="true"] .faq__icon::after { background: #fff; }
.faq__q[aria-expanded="true"] .faq__icon::after { transform: translate(-50%,-50%) scaleY(0); }
.faq__a {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.4s var(--ease);
}
.faq__a-inner {
  padding: 0 4px 28px;
  max-width: 70ch;
  color: var(--ink-soft);
  font-size: 16.5px;
}
.faq__a-inner p { margin: 0 0 0.8em; }
.faq__a-inner p:last-child { margin-bottom: 0; }

/* ============================================================
   CTA BAND
   ============================================================ */
.ctaband {
  background: var(--navy);
  color: #fff;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.ctaband::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(70% 120% at 100% 0%, rgba(201,169,97,0.16), transparent 55%),
    radial-gradient(60% 100% at 0% 100%, rgba(255,255,255,0.05), transparent 60%);
  z-index: -1;
}
/* padding-block for the same reason as .nav__inner: this is a `.wrap`, and
   the shorthand's `0` was overwriting the inline gutter it inherits. */
.ctaband__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
  padding-block: clamp(56px, 7vw, 96px);
}
@media (max-width: 820px) { .ctaband__inner { grid-template-columns: minmax(0, 1fr); gap: 28px; } }
.ctaband h2 { color: #fff; margin: 0 0 16px; }
.ctaband .em { color: var(--gold); }
.ctaband p { color: rgba(255,255,255,0.8); margin: 0; max-width: 48ch; }
.ctaband__actions {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: flex-start;
}
@media (max-width: 820px) { .ctaband__actions { align-items: stretch; } }
.ctaband__actions .btn { width: 100%; justify-content: space-between; }
.ctaband__note {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  margin-top: 6px;
}

/* ============================================================
   CONTACT
   ============================================================ */
.contact__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: clamp(28px, 5vw, 80px);
  align-items: start;
}
@media (max-width: 920px) { .contact__inner { grid-template-columns: minmax(0, 1fr); } }
.contact h2 { max-width: 16ch; }
.contact__meta {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.contact__meta dt {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
  margin-bottom: 4px;
}
.contact__meta dd { margin: 0; font-size: 16px; }

.formcard {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 40px);
}
form.inquire {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px;
}
form.inquire .full { grid-column: 1 / -1; }

.field {
  position: relative;
  display: block;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 22px 0 10px;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  border-radius: 0;
  transition: border-color 0.25s var(--ease);
  font-family: var(--sans);
}
.field select { appearance: none; background: transparent; padding-right: 24px; cursor: pointer; }
.field textarea { resize: vertical; min-height: 110px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--ink-accent);
}
.field label {
  position: absolute;
  left: 0;
  top: 22px;
  pointer-events: none;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mid);
  transition: transform 0.25s var(--ease), color 0.25s var(--ease);
}
.field input:focus + label,
.field input:not(:placeholder-shown) + label,
.field textarea:focus + label,
.field textarea:not(:placeholder-shown) + label,
.field.is-filled label,
.field select:focus + label {
  transform: translateY(-18px);
  color: var(--ink-accent);
}
.field .select-arrow {
  position: absolute;
  right: 0;
  top: 28px;
  pointer-events: none;
  color: var(--mid);
}
.field--error input,
.field--error select,
.field--error textarea {
  border-bottom-color: #b03a2e;
}
.field__error {
  display: none;
  margin-top: 6px;
  color: #b03a2e;
  font-size: 13px;
  font-family: var(--mono);
  letter-spacing: 0.1em;
}
.field--error .field__error { display: block; }

form.inquire .submit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}
form.inquire .submit p {
  font-size: 14px;
  color: var(--mid);
  margin: 0;
}
.form-success {
  display: none;
  margin-top: 16px;
  padding: 18px 20px;
  border: 1px solid var(--gold);
  background: var(--gold-soft);
  border-radius: 10px;
  color: #4a3608;
  font-size: 15.5px;
}
.form-success.is-on { display: block; }

@media (max-width: 600px) {
  form.inquire { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  background: var(--navy);
  color: rgba(255,255,255,0.76);
  padding: clamp(64px, 8vw, 100px) 0 36px;
}
/* `auto` on the brand track, not the 1.4fr it was. A fraction is a share of
   what is left over, and the brand column holds the one piece of content on
   this site that cannot be given a share: the lockup line has no spaces in it,
   so it has no break opportunity, so a track narrower than the line does not
   wrap it, it clips or overflows. At 1.4fr the column came to 324px at 1440
   and 265px at 1024 against a line that wanted 356px, and it broke on every
   desktop width the site was ever looked at. `auto` sizes the track from the
   content instead, so the column is whatever the lockup and the 36ch
   paragraph need and the three link columns divide the remainder. The line
   having no break opportunity is what makes this safe rather than fragile:
   min-content for this track is the whole line, so nothing downstream can
   squeeze it.

   Three link columns get three columns, not two with the third orphaned on a
   second row. 1080 matches the header, so the two halves of the page chrome
   change composition at the same width rather than at two arbitrary ones, and
   621 sends the lists to one column while there is still room to make that
   choice deliberately: at 620 the brand needs 264px of a 570px measure, so a
   phone gets a stacked footer with the lockup intact rather than a two-up
   grid overflowing its viewport. */
.footer__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 36px;
  padding-bottom: 56px;
  border-bottom: 1px solid rgba(255,255,255,0.12);
}
@media (max-width: 1080px) {
  .footer__top { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .footer__brand { grid-column: 1 / -1; margin-bottom: 16px; }
}
@media (max-width: 620px) {
  .footer__top { grid-template-columns: minmax(0, 1fr); gap: 28px; }
}
.footer__brand .logotype { color: #fff; }
.footer__brand .logotype small { color: var(--gold); }
.footer__brand p {
  margin-top: 22px;
  max-width: 36ch;
  color: rgba(255,255,255,0.7);
  font-size: 15.5px;
}
/* A footer column label is a real heading, it names the group of links
   under it, and somebody navigating by heading should be able to land on
   it. It was an h5 purely because h5 is small, which is exactly the wrong
   reason to pick a heading level. It is an h2 now, sized here. */
.footer__col h2 {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 18px;
  font-weight: 500;
  line-height: 1.4;
}
.footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.footer__col a {
  color: rgba(255,255,255,0.76);
  font-size: 15.5px;
}
.footer__col a:hover { color: #fff; }

.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding-top: 28px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  flex-wrap: wrap;
}
.footer__bottom a { color: rgba(255,255,255,0.7); }
.footer__bottom .sig { color: var(--gold); }

/* ============================================================
   BACK TO TOP
   ============================================================ */
.to-top {
  position: fixed;
  right: clamp(16px, 3vw, 32px);
  bottom: clamp(16px, 3vw, 32px);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  border: 1px solid var(--navy);
  display: grid;
  place-items: center;
  z-index: 60;
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), background 0.25s var(--ease);
  box-shadow: 0 12px 30px -14px rgba(10,31,62,0.6);
}
.to-top.is-on { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.to-top:hover { background: var(--navy-2); transform: translateY(-2px); }
.to-top svg { width: 18px; height: 18px; }

/* ============================================================
   404
   ============================================================ */
.error-page {
  min-height: 70vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--section-y) 0;
}
.error-page .code {
  font-family: var(--display);
  font-size: clamp(96px, 22vw, 240px);
  line-height: 0.9;
  color: var(--ink-accent);
  letter-spacing: -0.04em;
  font-weight: 500;
}
.error-page .code .em { color: var(--gold); }
.error-page h1 { font-size: clamp(28px, 4vw, 44px); margin: 16px 0 12px; }
.error-page p { color: var(--mid); max-width: 48ch; margin: 0 auto 28px; }
.error-page .actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

/* ============================================================
   REVEAL · scroll-triggered
   ============================================================ */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.reveal.is-in { opacity: 1; transform: translateY(0); }
.reveal[data-delay="1"] { transition-delay: 0.08s; }
.reveal[data-delay="2"] { transition-delay: 0.16s; }
.reveal[data-delay="3"] { transition-delay: 0.24s; }
.reveal[data-delay="4"] { transition-delay: 0.32s; }

/* skip link */
.skip {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px; height: 1px;
  overflow: hidden;
  background: var(--navy);
  color: #fff;
  padding: 12px 16px;
  border-radius: 6px;
  z-index: 200;
}
.skip:focus {
  left: 16px; top: 12px;
  width: auto; height: auto;
}

/* ============================================================
   PERSONAL-BRAND ADDITIONS (solo site)
   ============================================================ */

/* logotype: single-name personal brand */
.logotype .stack span:first-child { letter-spacing: -0.015em; }

/* service / workshop cards reuse .practice__card, with extras */
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.card-head .ix { margin: 0; }
.price-tag {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-gold-soft);
  background: var(--gold-soft);
  padding: 6px 11px;
  border-radius: 999px;
  white-space: nowrap;
}
.svc-lists { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; margin-top: 2px; }
@media (max-width: 560px) { .svc-lists { grid-template-columns: minmax(0, 1fr); } }
.svc-lists h4 {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--mid); margin: 0 0 10px; font-weight: 500;
  line-height: 1.4;
}
.svc-lists ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.svc-lists li {
  font-size: 15.5px; line-height: 1.4; color: var(--ink-soft);
  display: grid; grid-template-columns: 14px minmax(0, 1fr); gap: 8px;
}
.svc-lists li::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); margin-top: 7px; }
.price-line {
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.price-line .amt { font-family: var(--display); font-size: 22px; color: var(--ink-accent); letter-spacing: -0.01em; }
.price-line .amt small { font-family: var(--sans); font-size: 13.5px; color: var(--mid); font-weight: 500; letter-spacing: 0; }
.price-line .go { font-size: 15px; font-weight: 600; color: var(--ink-accent); display: inline-flex; gap: 8px; align-items: center; }
.price-line .go .arrow { transition: transform 0.3s var(--ease); }
.practice__card:hover .price-line .go .arrow { transform: translateX(4px); }

/* ---------- opt-in dark card ----------
   One card in a grid of light ones, inverted to say "this is not another
   item on the list, it is the way out of the list". The class carries the
   paint only; the lettering inside is already correct, because .on-dark is
   in the dark-field inventory above and every rule in the card asks a token
   rather than naming a colour. It replaced seven `style=` attributes, which
   is the real argument for it, inline colour is invisible to dark mode, to
   the print sheet, and to whoever changes the navy next. */
.on-dark {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--on-navy);
}
/* The one exception the tokens cannot make on their own: on a light card the
   price and its link share the navy accent, but on navy that accent is the
   body colour, and a link that matches the body is not a link. */
.on-dark .price-line .go { color: var(--gold-ink); }

/* co-facilitator note.

   `fit-content` rather than `auto`, because this is a flex column and a block
   child would stretch the full width of the card; and rather than
   `max-content` with a `max-width: 100%`, which is what stood here and did
   not work. That pair promises "hug the sentence, but never outgrow the
   card", and delivers only the first half: the percentage resolves to `auto`
   during intrinsic sizing, so all 338 pixels of "Co-facilitated with Hamilton
   Esteban, LMHC" were still offered to a card with 284 to give. See the
   shrink-to-fit note at the top of this file. */
.cofac {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--on-gold-soft); background: var(--gold-soft); padding: 6px 12px; border-radius: 999px;
  width: fit-content;
}
/* ---- ABOUT: TIMELINE ---- */
.tl { margin-top: 48px; border-top: 1px solid var(--rule); }
.tl__item {
  display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 32px;
  padding: 30px 0; border-bottom: 1px solid var(--rule);
}
@media (max-width: 720px) { .tl__item { grid-template-columns: minmax(0, 1fr); gap: 10px; } }
.tl__when { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-ink); padding-top: 4px; }
.tl__when span { display: block; color: var(--mid); margin-top: 4px; letter-spacing: 0.08em; }
.tl__role { font-family: var(--display); font-size: 23px; font-weight: 500; color: var(--ink-accent); margin: 0 0 4px; letter-spacing: -0.01em; }
.tl__org { font-size: 13.5px; color: var(--mid); margin: 0 0 12px; font-family: var(--mono); letter-spacing: 0.08em; text-transform: uppercase; }
.tl__item p { margin: 0; color: var(--ink-soft); font-size: 16px; }
.tl__item ul { margin: 12px 0 0; padding-left: 18px; color: var(--ink-soft); font-size: 15.5px; }
.tl__item li { margin-bottom: 6px; }

/* credentials grid */
.creds { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); margin-top: 48px; }
@media (max-width: 760px) { .creds { grid-template-columns: minmax(0, 1fr); } }
.creds > div { background: var(--card); padding: 26px 24px; }
.section--paper .creds > div { background: var(--paper); }
.creds h3 { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold-ink); margin: 0 0 14px; font-weight: 500; line-height: 1.4; }
.creds ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
.creds li { font-size: 15.5px; color: var(--ink-soft); line-height: 1.4; }
.creds li strong { color: var(--ink); font-weight: 600; }

/* skills chips */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chips span {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft); border: 1px solid var(--rule); padding: 8px 12px; border-radius: 999px; background: var(--card);
}
.section--paper .chips span { background: var(--card); }
/* footer non-affiliation disclaimer */
.footer__fine {
  margin: 18px 0 0;
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: 0.03em;
  color: rgba(255,255,255,0.42);
  max-width: 70ch;
}

/* ============================================================
   DECORATIVE BRAND GRAPHICS  (aria-hidden, behind content)
   ============================================================ */
.has-deco { position: relative; isolation: isolate; }
.has-deco > .wrap { position: relative; z-index: 1; }
.clip { overflow: hidden; }
.deco { position: absolute; pointer-events: none; z-index: 0; }
.deco-fill { inset: 0; }

/* dot grid (navy-tinted; gold on dark sections) */
.deco-dots { background-image: radial-gradient(rgba(10,31,62,0.08) 1px, transparent 1.3px); background-size: 26px 26px; }
.section--navy .deco-dots, .ctaband .deco-dots{ background-image: radial-gradient(rgba(201,169,97,0.16) 1px, transparent 1.3px); }

/* plus-mark motif (brand cross), kept faint so it never competes with text */
.deco-plus {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='54'%20height='54'%3E%3Cpath%20d='M27%2020v14M20%2027h14'%20stroke='%23c9a961'%20stroke-width='1'%20stroke-linecap='round'%20opacity='0.3'/%3E%3C/svg%3E");
  background-size: 54px 54px;
  opacity: 0.45;
}
/* on dark sections the gold reads a touch stronger, which is fine behind large headings */
.section--navy .deco-plus, .ctaband .deco-plus { opacity: 0.5; }

/* concentric rings */
.deco-rings {
  border-radius: 50%;
  background: repeating-radial-gradient(circle, transparent 0 33px, rgba(201,169,97,0.30) 33px 34px, transparent 34px 67px);
  -webkit-mask: radial-gradient(circle, #000 56%, transparent 72%);
  mask: radial-gradient(circle, #000 56%, transparent 72%);
}
.section--navy .deco-rings { background: repeating-radial-gradient(circle, transparent 0 33px, rgba(201,169,97,0.34) 33px 34px, transparent 34px 67px); }
/* soft glow */
.deco-glow { background: radial-gradient(circle at center, rgba(201,169,97,0.20), transparent 68%); }
/* fade masks for pattern fills */
.fade-tr { -webkit-mask-image: radial-gradient(95% 95% at 100% 0%, #000, transparent 70%); mask-image: radial-gradient(95% 95% at 100% 0%, #000, transparent 70%); }
.fade-bl { -webkit-mask-image: radial-gradient(95% 95% at 0% 100%, #000, transparent 70%); mask-image: radial-gradient(95% 95% at 0% 100%, #000, transparent 70%); }
.fade-tl { -webkit-mask-image: radial-gradient(95% 95% at 0% 0%, #000, transparent 70%); mask-image: radial-gradient(95% 95% at 0% 0%, #000, transparent 70%); }
/* gentle float (respects global reduced-motion reset) */
@keyframes deco-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
.deco-float { animation: deco-float 10s ease-in-out infinite; }

/* hide heavier accents on small screens to avoid clutter/overflow */
@media (max-width: 760px) { .deco-accent { display: none; } }
/* ============================================================
   AWARD / RECOGNITION BADGE
   ============================================================ */
/* The citation is 363px on one line and lives in a hero that has 280 on a
   320px screen, so it has to be able to become two lines, and the two lines
   have to be the two halves of the citation, not wherever the words happen to
   run out. `flex-wrap` on the pill plus a real element around the name is
   what makes the break fall between the publication and the honour; left as
   one anonymous run of text it broke as "Crain's New / York … / Business".
   The year is held together by `nowrap` for the same reason, without it the
   separator ended up opening a line, as "· 2025". */
.award {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px 9px;
  padding: 8px 15px;
  border-radius: 999px;
  border: 1px solid var(--gold);
  background: var(--white);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-accent);
  line-height: 1;
  letter-spacing: -0.005em;
  width: fit-content;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.award:hover { background: var(--gold-soft); transform: translateY(-1px); box-shadow: 0 10px 24px -16px var(--navy-glow); }
.award .seal { width: 17px; height: 17px; color: var(--gold-ink); flex: none; }
.award .yr { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; color: var(--gold-ink); white-space: nowrap; }
/* Wrapping is the safety net, not the plan. Once the pill was allowed to
   shrink to fit it stopped running off a 320px screen, but it also started
   breaking onto two lines at 390 and 360, the two commonest handsets, where
   it had only ever appeared to fit because it was overhanging its own column
   by thirteen pixels and the viewport happened to be wide enough to hide the
   evidence. It asks for 363px and a 390px phone has 350 to give.

   Half a point of type, two pixels of padding on each side, and a little less
   tracking on the year bring it to 316, which is one line on both. At 320 it
   still wraps, and it should: nothing fits on one line there, and the
   two-line pill is legible and deliberate, which is what makes this safe to
   tune finely. The worst case if the mono webfont fails to load and the
   fallback measures wider is the wrap we already know reads well. */
@media (max-width: 420px) {
  .award { font-size: 12px; padding: 7px 11px; gap: 2px 6px; letter-spacing: -0.01em; }
  .award .seal { width: 15px; height: 15px; }
  .award .yr { font-size: 10px; letter-spacing: 0.02em; }
}
/* feature card (e.g. About credentials) */
.award-feature {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  padding: 18px 26px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--gold);
  background: linear-gradient(180deg, var(--white), var(--paper));
  width: fit-content;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.award-feature:hover { transform: translateY(-2px); box-shadow: 0 24px 50px -40px var(--navy-glow); }
.award-feature__seal {
  width: 48px; height: 48px;
  border-radius: 50%;
  display: grid; place-items: center;
  flex: none;
  background: var(--navy);
  color: var(--gold);
}
.award-feature__seal svg { width: 24px; height: 24px; }
.award-feature__txt { display: flex; flex-direction: column; gap: 3px; }
.award-feature__txt .k { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold-ink); }
.award-feature__txt .v { font-family: var(--display); font-size: 20px; color: var(--ink-accent); letter-spacing: -0.01em; line-height: 1.1; }
.award-feature__txt .yr { font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em; color: var(--mid); }
@media (max-width: 560px) {
  .award-feature { gap: 14px; padding: 16px 18px; }
  .award-feature__txt .v { font-size: 17px; }
}

/* about hero portrait tile

   Three layers in one 4:5 frame, and their order matters more than it looks.
   The svg is the ground: it shows while the photograph is still arriving and,
   via the img's onerror, if it never arrives at all. The photograph covers it.
   The chip sits over whichever of the two is showing, that is what a chip is
   for, so it has to be numbered above the photograph rather than left on
   `auto`.

   It was left on `auto`, and a positioned element with a positive z-index
   paints after every positioned element without one no matter what the source
   order says. So the photograph buried it: the chip appeared for exactly as
   long as the image took to load and then disappeared, on both pages, on
   every visit. Nothing caught it because nothing was obscured *badly* enough
   to overflow, misalign, or fail contrast, it was simply gone. buried.py now
   asks the question directly. */
.about-portrait {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4/5;
  position: relative;
  background: var(--navy);
}
.about-portrait svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.about-portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 18%;
  z-index: 1;
}
.about-portrait .label {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 2;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(0, 0, 0, 0.28);
  padding: 6px 10px;
  border-radius: 999px;
  backdrop-filter: blur(4px);
}


/* ============================================================
   2026 REFRESH · polish layer
   ============================================================ */

/* anchored sections no longer hide under the sticky nav */
[id] { scroll-margin-top: 96px; }

/* warm editorial glow behind heroes */
.hero, .page-hero {
  background:
    radial-gradient(900px 480px at 88% -10%, rgba(201,169,97,0.13), transparent 62%),
    radial-gradient(700px 420px at -8% 110%, rgba(10,31,62,0.045), transparent 60%);
}

/* (The italic emphasis on inner-page heroes is underlined by the same rule
   that serves the home page, see `.hero h1 .em, .page-hero h1 .em` above.) */

/* buttons: deeper primary, satisfying press */
.btn--primary { background: linear-gradient(180deg, #11294f, var(--navy)); }
.btn--primary:hover { background: linear-gradient(180deg, #14325e, var(--navy-2)); }
.btn:active { transform: translateY(0) scale(0.985); }
/* stronger card lift */
.practice__card:hover{ transform: translateY(-4px); }

/* copy-email button (contact) */
.copybtn {
  margin-left: 10px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-ink);
  background: transparent;
  border: 1px solid var(--gold);
  border-radius: 999px;
  padding: 5px 12px;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
  vertical-align: 2px;
}
.copybtn:hover { background: var(--gold-soft); }
.copybtn.is-copied { background: var(--navy); border-color: var(--ink-accent); color: #fff; }

/* There was a second, smaller @media print here that said a weaker version
   of what the PRINT section below says properly. Two print blocks in one
   stylesheet is how a print sheet quietly rots: you fix the one you find. */


/* ============================================================
   LEADERSHIP · CAREER · FINANCES  HUB LAYER  (2026 relaunch)
   Personal-brand hub: newsletter-first, YouTube + free tools,
   three content pillars. Extends the navy/gold system with
   restrained per-topic accents that harmonize with gold.

   The three ramps are named for the three topics, in tagline order,
   and they are renamed whenever the tagline is. --lead is the old
   --life ramp and --finances the old --money one; both hues were
   already contrast-checked, so only the names and the pillars they
   serve changed. That sounds like tidiness and is not. A token called
   --money outlived the word on the page by one relaunch, and the six
   video cards on watch.html were still labelled MONEY and LIFE when
   every visible pillar had read LEADERSHIP, CAREER, FINANCES for
   weeks: the internal name is where a retired vocabulary hides, and
   the next person to add a card reaches for the name they can see in
   the stylesheet. vocab.py now reads the tagline out of build.py and
   checks the rendered labels against it, so the page cannot drift;
   these names are kept in step by hand so the source cannot either.
   ============================================================ */
:root{
  --lead:#c17a48;      --lead-soft:#f3e6d9;      --lead-deep:#8f5228;
  --career:#3a5f8f;    --career-soft:#dde7f3;    --career-deep:#2b466a;
  --finances:#2f7d5b;  --finances-soft:#dcefe4;  --finances-deep:#245f45;
  --yt:#ff2a2a;        --yt-deep:#d40000;
}

/* ---------- topic tag ---------- */
.ttag{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--mono); font-size:11.5px; letter-spacing:0.16em; text-transform:uppercase;
  padding:6px 11px; border-radius:999px; border:1px solid var(--rule);
  color:var(--mid); background:var(--card); white-space:nowrap; width:max-content;
}
.ttag::before{ content:""; width:7px; height:7px; border-radius:50%; background:var(--gold); flex:none; }
.ttag--finances{ color:var(--finances-deep); border-color:transparent; background:var(--finances-soft); }
.ttag--finances::before{ background:var(--finances); }
.ttag--career{ color:var(--career-deep); border-color:transparent; background:var(--career-soft); }
.ttag--career::before{ background:var(--career); }
.ttag--lead{ color:var(--lead-deep); border-color:transparent; background:var(--lead-soft); }
.ttag--lead::before{ background:var(--lead); }

/* ---------- nav: compact youtube icon link ---------- */
.nav__yt{
  display:inline-grid; place-items:center; width:38px; height:38px;
  border-radius:8px; border:1px solid var(--rule); color:var(--ink-accent);
  transition:background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.nav__yt:hover{ background:var(--paper); border-color:var(--ink-accent); }
.nav__yt svg{ width:19px; height:19px; }
@media (max-width: 1080px){ .nav__yt{ display:none; } }.btn--yt-ghost{ background:transparent; color:var(--ink); border-color:var(--rule); }
.btn--yt-ghost:hover{ border-color:var(--yt); color:var(--yt-deep); transform:translateY(-1px); }
.btn--yt-ghost svg{ width:18px; height:18px; color:var(--yt); }

/* ============================================================
   NEWSLETTER SIGNUP  (primary CTA across the site)
   ============================================================ */
.news{ display:flex; flex-direction:column; gap:14px; }
.news__form{ display:flex; gap:10px; flex-wrap:wrap; align-items:stretch; }
.news__form input[type="email"]{
  flex:1 1 clamp(220px, 40vw, 340px); min-width:0;
  font-family:var(--sans); font-size:16px; color:var(--ink); font-weight:500;
  background:var(--card); border:1px solid var(--rule); border-radius:999px; padding:14px 20px;
  transition:border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.news__form input[type="email"]::placeholder{ color:#9aa3b0; font-weight:400; }
.news__form input[type="email"]:focus{ outline:none; border-color:var(--ink-accent); box-shadow:0 0 0 3px var(--navy-glow); }
.news__form .btn{ flex:none; }
.news__note{
  font-family:var(--mono); font-size:12.5px; letter-spacing:0.06em; color:var(--mid);
  display:inline-flex; align-items:center; gap:8px;
}
.news__note svg{ width:14px; height:14px; color:var(--gold-ink); flex:none; }
.news__ok{
  display:none; align-items:center; gap:10px;
  padding:14px 18px; border:1px solid var(--gold); background:var(--gold-soft);
  border-radius:12px; color:#4a3608; font-size:15.5px; font-weight:500;
}
.news__ok.is-on{ display:flex; }
.news__ok svg{ width:18px; height:18px; color: var(--gold-ink); flex:none; }

/* newsletter on dark (navy hero panel / ctaband) */
.on-navy .news__form input[type="email"],
.section--navy .news__form input[type="email"],
.ctaband .news__form input[type="email"]{
  background:rgba(255,255,255,0.08); border-color:rgba(255,255,255,0.28); color:#fff;
}
.on-navy .news__form input[type="email"]::placeholder,
.section--navy .news__form input[type="email"]::placeholder,
.ctaband .news__form input[type="email"]::placeholder{ color:rgba(255,255,255,0.6); }
.on-navy .news__form input[type="email"]:focus,
.section--navy .news__form input[type="email"]:focus,
.ctaband .news__form input[type="email"]:focus{ border-color:var(--focus-ring); box-shadow:0 0 0 3px var(--focus-halo); }
.on-navy .news__note,
.section--navy .news__note,
.ctaband .news__note{ color:rgba(255,255,255,0.6); }
.on-navy .news__note svg,
.section--navy .news__note svg,
.ctaband .news__note svg{ color:var(--gold); }

/* ============================================================
   CONTENT PILLARS  (Money / Career / Life)
   ============================================================ */
.pillars{ display:grid; grid-template-columns:repeat(3,minmax(0, 1fr)); gap:24px; margin-top:52px; }
@media (max-width: 860px){ .pillars{ grid-template-columns:minmax(0, 1fr); } }
.pillar{
  border:1px solid var(--rule); border-radius:var(--radius-lg); padding:32px 30px;
  background:var(--card); display:flex; flex-direction:column; gap:16px; position:relative; overflow:hidden;
  transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.section--paper .pillar{ background:var(--card); }
.pillar:hover{ transform:translateY(-4px); box-shadow:0 30px 60px -50px var(--navy-glow); }
.pillar::before{ content:""; position:absolute; left:0; top:0; right:0; height:3px; background:var(--gold); }
.pillar--finances::before{ background:var(--finances); }
.pillar--career::before{ background:var(--career); }
.pillar--lead::before{ background:var(--lead); }
.pillar__icon{ width:48px; height:48px; border-radius:13px; display:grid; place-items:center; color:#fff; flex:none; }
.pillar__icon svg{ width:24px; height:24px; }
.pillar--finances .pillar__icon{ background:var(--finances); }
.pillar--career .pillar__icon{ background:var(--career); }
.pillar--lead .pillar__icon{ background:var(--lead); }
.pillar h3{ font-family:var(--display); font-size:25px; color:var(--ink-accent); margin:0; letter-spacing:-0.01em; font-weight:500; }
.pillar p{ color:var(--ink-soft); font-size:16px; margin:0; }
.pillar__topics{ list-style:none; margin:4px 0 0; padding:0; display:flex; flex-direction:column; gap:8px; }
.pillar__topics li{ font-size:15px; color:var(--mid); display:grid; grid-template-columns:16px minmax(0, 1fr); gap:8px; line-height:1.4; }
.pillar__topics li::before{ content:""; width:6px; height:6px; border-radius:50%; margin-top:7px; background:var(--gold); }
.pillar--finances .pillar__topics li::before{ background:var(--finances); }
.pillar--career .pillar__topics li::before{ background:var(--career); }
.pillar--lead .pillar__topics li::before{ background:var(--lead); }
.pillar .go{ margin-top:auto; padding-top:18px; border-top:1px solid var(--rule); font-size:15px; font-weight:600; color:var(--ink-accent); display:inline-flex; align-items:center; gap:8px; }
.pillar .go .arrow{ transition:transform 0.3s var(--ease); }
.pillar:hover .go .arrow{ transform:translateX(4px); }

/* ============================================================
   TOOL CARDS  (tools hub + home tools band)
   ============================================================ */
.toolgrid{ display:grid; grid-template-columns:repeat(2,minmax(0, 1fr)); gap:22px; margin-top:48px; }
@media (max-width: 760px){ .toolgrid{ grid-template-columns:minmax(0, 1fr); } }
.toolcard{
  display:flex; flex-direction:column; gap:14px; position:relative;
  border:1px solid var(--rule); border-radius:var(--radius-lg); padding:28px; background:var(--card);
  transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.section--paper .toolcard{ background:var(--card); }
.toolcard:hover{ transform:translateY(-4px); border-color:var(--ink-accent); box-shadow:0 30px 60px -50px var(--navy-glow); }
.toolcard__top{ display:flex; align-items:flex-start; justify-content:space-between; gap:14px; }
.toolcard__icon{ width:46px; height:46px; border-radius:12px; background:var(--navy); color:var(--gold); display:grid; place-items:center; flex:none; }
.toolcard__icon svg{ width:23px; height:23px; }
.toolcard h3{ font-family:var(--display); font-size:23px; color:var(--ink-accent); margin:0; letter-spacing:-0.01em; font-weight:500; }
.toolcard p{ color:var(--ink-soft); font-size:16px; margin:0; }
.toolcard .go{ margin-top:auto; padding-top:18px; border-top:1px solid var(--rule); font-size:15px; font-weight:600; color:var(--ink-accent); display:inline-flex; align-items:center; justify-content:space-between; gap:8px; }
.toolcard .go .arrow{ transition:transform 0.3s var(--ease); }
.toolcard:hover .go .arrow{ transform:translateX(4px); }
/* full-bleed link wrapper so the whole card is clickable */
a.toolcard{ color:inherit; }

/* ============================================================
   VIDEO CARDS  (watch / youtube hub)
   ============================================================ */
.videos{ display:grid; grid-template-columns:repeat(3,minmax(0, 1fr)); gap:22px; margin-top:44px; }
@media (max-width: 900px){ .videos{ grid-template-columns:repeat(2,minmax(0, 1fr)); } }
@media (max-width: 600px){ .videos{ grid-template-columns:minmax(0, 1fr); } }
.videocard{ border:1px solid var(--rule); border-radius:var(--radius-lg); overflow:hidden; background:var(--card); display:flex; flex-direction:column; transition:transform 0.3s var(--ease), box-shadow 0.3s var(--ease); }
.videocard:hover{ transform:translateY(-3px); box-shadow:0 30px 60px -50px var(--navy-glow); }
.videocard__thumb{ aspect-ratio:16/9; position:relative; background:var(--navy); overflow:hidden; display:grid; place-items:center; isolation:isolate; }
.videocard__thumb::before{ content:""; position:absolute; inset:0; background:radial-gradient(120% 90% at 100% 0%, rgba(201,169,97,0.20), transparent 55%), radial-gradient(80% 70% at 0% 100%, rgba(255,255,255,0.06), transparent 60%); z-index:-1; }
.videocard__thumb .play{ width:56px; height:56px; border-radius:50%; background:rgba(255,255,255,0.14); border:1px solid rgba(255,255,255,0.42); display:grid; place-items:center; color:#fff; backdrop-filter:blur(3px); }
.videocard__thumb .play svg{ width:22px; height:22px; margin-left:2px; }
.videocard__thumb .badge-soon{ position:absolute; top:12px; left:12px; font-family:var(--mono); font-size:11.5px; letter-spacing:0.18em; text-transform:uppercase; color:#fff; background:rgba(0,0,0,0.35); border:1px solid rgba(255,255,255,0.25); padding:5px 10px; border-radius:999px; backdrop-filter:blur(4px); }
.videocard__body{ padding:20px 22px 24px; display:flex; flex-direction:column; gap:9px; }
.videocard__body h3{ font-family:var(--display); font-size:19px; font-weight:500; color:var(--ink); margin:0; line-height:1.2; letter-spacing:-0.005em; }
.videocard__body p{ font-size:15px; color:var(--mid); margin:0; }
.videocard__meta{ font-family:var(--mono); font-size:11.5px; letter-spacing:0.16em; text-transform:uppercase; color: var(--gold-ink); }

/* ---------- coming-soon chip ---------- */
.soon-chip{ display:inline-flex; align-items:center; gap:8px; font-family:var(--mono); font-size:11.5px; letter-spacing:0.18em; text-transform:uppercase; color: var(--on-gold-soft); background:var(--gold-soft); padding:6px 12px; border-radius:999px; width:max-content; }
.soon-chip .dot{ width:6px; height:6px; border-radius:50%; background:var(--gold-ink); box-shadow:0 0 0 3px rgba(201,169,97,0.25); }

/* ============================================================
   GEARS  (Park / Neutral / Drive · leadership framework)
   ============================================================ */
.gears{ display:grid; grid-template-columns:repeat(3,minmax(0, 1fr)); gap:18px; margin-top:36px; }
@media (max-width: 760px){ .gears{ grid-template-columns:minmax(0, 1fr); } }
.gear{ border:1px solid var(--rule); border-radius:var(--radius-lg); padding:26px 24px; background:var(--card); display:flex; flex-direction:column; gap:12px; position:relative; overflow:hidden; }
.gear__badge{ display:inline-flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:12px; font-family:var(--display); font-weight:600; font-size:22px; flex:none; }
.gear--park .gear__badge{ background:#eceff3; color:#5b6472; }
.gear--neutral .gear__badge{ background:var(--gold-soft); color: var(--on-gold-soft); }
.gear--drive .gear__badge{ background:var(--navy); color:var(--gold); }
.gear__k{ font-family:var(--mono); font-size:11.5px; letter-spacing:0.2em; text-transform:uppercase; color:var(--mid); }
.gear h3{ font-family:var(--display); font-size:21px; font-weight:500; color:var(--ink-accent); margin:0; letter-spacing:-0.01em; }
.gear p{ font-size:16px; color:var(--ink-soft); margin:0; line-height:1.5; }
.gear--drive{ border-color:var(--gold); }
.section--navy .gear--drive{ border-color:rgba(201,169,97,0.55); }

/* ============================================================
   FEATURE ROW  (image/graphic + copy, reusable)
   ============================================================ */
.featurerow{ display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); gap:clamp(28px,5vw,72px); align-items:center; }
@media (max-width: 860px){ .featurerow{ grid-template-columns:minmax(0, 1fr); gap:32px; } }
/* channel/preview tile (navy graphic) */
.channel-tile{ position:relative; border-radius:var(--radius-lg); overflow:hidden; aspect-ratio:16/10; background:var(--navy); display:grid; place-items:center; isolation:isolate; }
.channel-tile::before{ content:""; position:absolute; inset:0; background:radial-gradient(110% 80% at 100% 0%, rgba(201,169,97,0.22), transparent 55%), radial-gradient(80% 70% at 0% 100%, rgba(255,255,255,0.06), transparent 60%); z-index:-1; }
.channel-tile__play{ width:74px; height:74px; border-radius:50%; background:var(--yt); display:grid; place-items:center; color:#fff; box-shadow:0 18px 40px -16px rgba(0,0,0,0.6); }
.channel-tile__play svg{ width:30px; height:30px; margin-left:3px; }
.channel-tile__label{ position:absolute; left:18px; bottom:18px; font-family:var(--mono); font-size:11.5px; letter-spacing:0.2em; text-transform:uppercase; color:var(--ink-soft); }

/* ---------- a cover for a book that does not exist yet ----------
   Set in type rather than shown as a picture: there is no jacket to
   photograph, nothing to redraw when there is one, and nothing for a
   reader to download in the meantime. It sits on a .channel-tile, so
   the dark-field tokens are already in scope. */
.bookcover{ aspect-ratio:4/5; }
.bookcover__inner{ text-align:center; padding:0 24px; }
.bookcover__pre{ font-family:var(--mono); font-size:11.5px; letter-spacing:0.24em; text-transform:uppercase; color:var(--gold-ink); }
.bookcover__title{
  font-family:var(--display); font-style:italic; font-weight:500;
  font-size:clamp(34px,4vw,46px); line-height:1.05;
  color:var(--ink); margin:14px 0 10px;
}
.bookcover__rule{ width:44px; height:2px; background:var(--gold-ink); margin:16px auto; border:0; }
.bookcover__by{ font-family:var(--mono); font-size:11.5px; letter-spacing:0.16em; text-transform:uppercase; color:var(--mid); }

/* small stat/hook row inside cards */
.minihooks{ display:flex; flex-wrap:wrap; gap:8px; }
.minihooks span{ font-family:var(--mono); font-size:11.5px; letter-spacing:0.12em; text-transform:uppercase; color:var(--ink-soft); border:1px solid var(--rule); background:var(--card); padding:7px 11px; border-radius:999px; }

/* prose intro block (leadership / content pages) */
.prose{ max-width:70ch; }
/* Half-width column, so the measure has to come in with it, 70ch would
   simply be overruled by the grid track and stop meaning anything. */
.prose--narrow{ max-width:46ch; }
.prose p{ font-size:17px; line-height:1.62; color:var(--ink-soft); margin:0 0 1.1em; }
.prose p .em{ color:var(--ink-accent); }
.prose h3{ font-family:var(--display); font-size:26px; color:var(--ink-accent); margin:1.6em 0 0.5em; font-weight:500; letter-spacing:-0.01em; }
.prose strong{ color:var(--ink); font-weight:600; }
.pull{ font-family:var(--display); font-style:italic; font-size:clamp(22px,2.6vw,30px); line-height:1.3; color:var(--ink-accent); border-left:2px solid var(--gold); padding-left:24px; margin:36px 0; max-width:30ch; }


/* ============================================================
   DARK THEME PATCHES
   The token swap does most of the work. These are the places
   where a colour was doing structural duty and needs an explicit
   counterpart on a dark field.
   ============================================================ */
:root[data-theme="dark"] .nav { background: rgba(10,16,23,0.82); }
:root[data-theme="dark"] .nav.is-scrolled {
  background: rgba(10,16,23,0.94);
  box-shadow: 0 12px 32px -26px rgba(0,0,0,0.9);
}

/* Navy panels invert their relationship to the page: on paper they
   sink, on a dark field they lift. A hairline keeps the edge legible. */
:root[data-theme="dark"] .section--navy,
:root[data-theme="dark"] .ctaband {
  color: var(--on-navy);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
}
:root[data-theme="dark"] .footer {
  background: var(--paper);
  color: var(--ink-soft);
  border-top: 1px solid var(--rule);
}

/* Primary action needs to be the brightest thing on the screen.
   On paper that is navy; on a dark field it is gold. */
:root[data-theme="dark"] .btn--primary {
  background: var(--gold);
  color: #10192a;
  border-color: var(--gold);
  font-weight: 700;
}
:root[data-theme="dark"] .btn--primary:hover {
  background: #e7c98a;
  border-color: #e7c98a;
  box-shadow: 0 10px 30px -12px rgba(217,186,118,0.45);
}
:root[data-theme="dark"] .btn--light { background: var(--gold); color: #10192a; border-color: var(--gold); }
:root[data-theme="dark"] .btn--ghost { border-color: var(--rule); }
:root[data-theme="dark"] .btn--ghost:hover { border-color: var(--gold); color: var(--gold); }

/* Hero wash: cool, not warm, so the gold accent still reads. */
:root[data-theme="dark"] .hero,
:root[data-theme="dark"] .page-hero {
  background:
    radial-gradient(900px 480px at 88% -10%, rgba(201,169,97,0.10), transparent 62%),
    radial-gradient(700px 420px at -8% 110%, rgba(90,140,220,0.07), transparent 60%);
}

/* Logotype mark: navy-on-navy disappears, so give it a gold hairline. */
:root[data-theme="dark"] .logotype .mark {
  background: var(--navy-2);
  box-shadow: inset 0 0 0 1px rgba(201,169,97,0.35);
}

/* Photography carries a lot of light. Take a little off so it sits
   inside the page rather than glowing out of it. */
:root[data-theme="dark"] img:not([src$=".svg"]) { filter: brightness(0.92) contrast(1.02); }

/* Decorative pattern fills were tuned against paper. */
:root[data-theme="dark"] .deco { opacity: 0.55; }
:root[data-theme="dark"] .deco-fill { filter: invert(1) brightness(1.6); }

/* Form fields on the light field of a card.

   The `:not(:focus)` is load-bearing, and it is the fix for a bug that was
   invisible to read and obvious to measure. `:root[data-theme="dark"] input`
   scores (0,2,1), exactly the same as `.field input:focus`, and sits eight
   hundred lines further down, so it won on source order. The contact form's
   focus border therefore never changed colour in the dark theme: six fields
   whose only remaining indication was a 1.5:1 halo.

   A theme rule describes a resting state. Saying so in the selector is what
   stops it from quietly outranking every state rule that comes before it,
   and it keeps working if these blocks are ever reordered. */
:root[data-theme="dark"] input:not(:focus),
:root[data-theme="dark"] select:not(:focus),
:root[data-theme="dark"] textarea:not(:focus) { border-color: var(--rule); }
:root[data-theme="dark"] input,
:root[data-theme="dark"] select,
:root[data-theme="dark"] textarea { background: var(--surface); color: var(--ink); }
:root[data-theme="dark"] .news__form input[type="email"] { background: var(--surface); color: var(--ink); }
:root[data-theme="dark"] .news__form input[type="email"]::placeholder { color: var(--mid); }
:root[data-theme="dark"] .chips span,
:root[data-theme="dark"] .minihooks span { background: var(--surface); }


/* ============================================================
   THEME TOGGLE
   Two-state switch in the nav. Ships pressed-state semantics so
   screen readers announce the current theme, not just the control.
   ============================================================ */
.themetoggle {
  width: 36px; height: 36px;
  display: inline-grid; place-items: center;
  border-radius: 8px;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink-accent);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
  flex: none;
}
.themetoggle:hover { background: var(--paper); border-color: var(--gold); transform: translateY(-1px); }
.themetoggle svg { width: 17px; height: 17px; }
.themetoggle .icon-moon { display: none; }
:root[data-theme="dark"] .themetoggle .icon-sun { display: none; }
:root[data-theme="dark"] .themetoggle .icon-moon { display: block; }
@media (max-width: 980px) { .themetoggle { display: none; } }
.mobile-sheet .themetoggle {
  display: inline-flex; width: auto; height: auto;
  gap: 10px; padding: 12px 18px; border-radius: 999px;
  font-size: 15.5px; font-weight: 600;
}
@media (max-width: 980px) { .mobile-sheet .themetoggle { display: inline-flex; } }


/* ============================================================
   PRINT

   Every browser's print dialog ships with "Background graphics"
   switched off, and that one default decides how this section has
   to be written. A navy panel with white lettering is the site's
   best-looking object on screen and the worst thing that can
   happen to it on paper: the fill is dropped, the lettering is
   not, and the most important number on the sheet prints white on
   white. `print-color-adjust: exact` would force the fill back,
   but only in browsers that honour it and only on a printer with
   ink to spare, so it is not used for anything a reader needs.

   The rule instead is that the printed sheet is black on white by
   construction. Every dark panel becomes paper and everything
   inside it goes back to ink. That survives a cheap laser, a
   draft-mode cartridge, a photocopy, and a fax.
   ============================================================ */
@media print {
  :root, :root[data-theme="dark"] {
    --bg: #fff; --card: #fff; --paper: #fff; --surface: #fff;
    --ink: #000; --ink-soft: #1a1a1a; --ink-accent: #0a1f3e; --mid: #444;
    --rule: #c8c8c8; --navy: #0a1f3e;
    /* Gold is a 2.2:1 whisper on white. On screen --gold-ink solves that by
       darkening; on paper there is no reason to spend a colour cartridge on
       an eyebrow, so the whole family collapses to ink. */
    --gold: #000; --gold-ink: #000; --gold-deep: #000; --on-gold-soft: #000;
    --gold-soft: transparent;
    color-scheme: light;
  }
  @page { margin: 14mm; }
  html { font-size: 92%; }
  body { background: #fff !important; color: #000; }

  /* Chrome you cannot use on paper. A button is an invitation to click. */
  .nav, .mobile-sheet, .to-top, .progress, .deco, .ctaband, .skip,
  .themetoggle, .news, #newsletter, .noprint, .videocard__badge,
  .btn, .cta-row, .hero__cta, .t-share, .copybtn { display: none !important; }

  /* Every band on the page, not every band that happens to be spelled
     `.section`. This rule was one selector for a long time and it was
     measurably wrong: `.page-hero` printed its full 48px/40px of screen air
     on seven pages, `.hero` printed 43px/60px on the home page, and
     `.section--tight` printed 48px on About while the identical modifier on
     Workshops printed 12px, because that one happens to carry `.section`
     alongside it and About's does not. So the same modifier behaved
     differently on two pages and neither behaviour was chosen.

     Screen air is the first thing paper should lose: the page margin is
     already the frame, and a 48px band opening costs a third of an inch on
     every sheet it appears on. Together these accounted for 88px on About
     and 64px on the newsletter, which is why both of them were spilling a
     footer onto a sheet of its own. `--tight` and `--paper` flatten to the
     same value here on purpose; tight-versus-loose is screen rhythm, and
     print has never honoured it for `.section` either.

     Bands on the tool pages are deliberately absent: they are set to zero
     further down, where the results panel becomes the document. printcheck
     measures this rather than trusting it, because the failure mode is a
     new band class that no selector here names, which looks exactly like
     nothing. */
  .section, .section--tight, .page-hero, .hero { padding: 12px 0 !important; }

  /* ---- dark panels become paper ----------------------------------
     The same list the screen stylesheet uses to redeclare --gold-ink,
     which is not a coincidence: it is the site's inventory of "this
     is a dark field". There it means "gold is readable here"; here it
     means "nothing painted is coming, put the ink back". Keeping one
     list for both is what stops the next dark panel from being fixed
     on screen and forgotten on paper. */
  .section--navy, .hero__panel, .footer,
  .toolnews, .about-portrait, .channel-tile,
  .videocard__thumb, .toolcard__icon,
  .award-feature__seal, .gear--drive .gear__badge, .on-dark,
  .res-top, .marker-flag, .badge-soon, .hero__badge, .soon-chip, .price-tag {
    background: #fff !important;
    background-image: none !important;
    color: #000 !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }
  /* Descendants were coloured for a field that is no longer there, white
     lettering, translucent white captions, gold-on-navy eyebrows. Inheriting
     is the only rule that catches all of them, including the ones written
     after this stylesheet was last read. */
  .section--navy *, .hero__panel *, .footer *, .toolnews *, .res-top *, .on-dark * { color: inherit !important; }

  /* The printed footer is the smallest useful thing that still discloses.
     It is tight for a reason beyond taste: a calculator result runs just
     under two pages, so a footer block of an inch and a half is the
     difference between a plan somebody pins up and a plan that arrives with
     a second sheet carrying nothing but the small print.

     Two of these are corrections to screen rules that had no business
     travelling to paper. `.footer__bottom` is a space-between flex row with
     28px of air above it, spacing for a wide navy band that print has
     already turned white, and on a 695px column it wrapped its two spans
     onto separate lines, spending 78px on one line of type. It is left-
     aligned and unpadded here instead. `.footer__fine` is capped at 70ch on
     screen because a 100-character measure is unreadable at 11px; at 7.5pt
     on a column this narrow the cap is doing nothing but adding two lines,
     so it is lifted. The disclaimer itself is not negotiable and prints in
     full, the point is to make it cost five lines instead of eight. */
  .footer { border-top: 1px solid #c8c8c8; padding: 8px 0 0; margin-top: 12px; }
  .footer__top, .footer__col { display: none !important; }
  .footer__bottom { padding-top: 0; justify-content: flex-start; gap: 12px;
                    font-size: 7pt; letter-spacing: 0.12em; }

  /* Where the sheet came from, on the line that is already there.

     A printout outlives the tab it was made in, so it has to carry its own
     address. That used to be a `main::after` band with its own 18px of air,
     its own hairline rule and its own line of type, sitting two centimetres
     above the footer's hairline rule: two seams doing one job, 45px, at the
     bottom of every sheet. It also never once printed, because the rule
     written to switch it off on the calculator pages was spelled `#main`,
     and every page on this site spells its main element `<main id="main">`.
     So the site has been printing with no provenance at all, and the cost of
     the band was the only part that was hypothetical.

     Putting it in the footer row costs nothing at all, because the row was
     already saying something the sheet does not need twice: `Bronx, NY.
     Leadership, career & finances.` repeats the tagline that the disclaimer
     underneath it and the logotype above it both carry. The address does not
     appear anywhere else on paper. So the tagline stands down and the URL
     takes its place, in the same row, at the same height, under the one
     remaining rule. */
  .footer__bottom > span:last-child { display: none; }
  .footer__bottom::after { content: "Printed from hctor.com"; }
  .footer__fine { margin: 5px 0 0; max-width: none;
                  font-size: 7.5pt; line-height: 1.45; color: #333 !important; }

  .reveal { opacity: 1 !important; transform: none !important; }
  h1, h2, h3, h4 { break-after: avoid-page; }

  /* Only things that fit on a page are told not to break.
     `break-inside: avoid` on a block taller than the sheet is a contradiction,
     and the browser resolves it the expensive way: it starts the block on a
     fresh page, then breaks it anyway. Nothing is gained and a sheet is spent,
     and because the heading above is glued to it by the rule on the line
     before, the heading travels too, so page one of a printed result came out
     of the printer carrying a four-word eyebrow and nothing else. Cards are
     listed here; the tall result panels are not, and their real seams are
     named further down instead. */
  .toolcard, .pillar, .gear, .practice__card { break-inside: avoid; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 8pt; color: #555; word-break: break-all; }
  a[href^="#"]::after, a[href^="mailto"]::after { content: ""; }

}


/* ============================================================
   FORCED COLORS / HIGH CONTRAST
   ============================================================ */
@media (forced-colors: active) {
  .btn, .toolcard, .pillar, .gear{ border: 1px solid ButtonBorder; }
  .deco, .progress { display: none; }
  :focus-visible { outline: 3px solid Highlight; }
}


/* ============================================================
   TOOL CHARTS
   Two calculators draw an SVG area chart. Both used to hardcode
   navy for the line and near-white for the gridlines, which meant
   the chart disappeared entirely against a dark card. Nothing here
   is set in the markup any more, the script emits classes only,
   and every colour resolves through a token, so the chart follows
   the theme, print, and forced-colors like the rest of the site.
   ============================================================ */
:root {
  --chart-line: var(--navy);
  --chart-grid: var(--rule);
  --chart-label: var(--mid);
  --chart-dot: var(--gold);
  --chart-fill-strong: 0.16;
}
:root[data-theme="dark"] {
  /* Navy on navy is invisible. In dark the line lifts to a cool
     light blue, still reads as "the money line", still not gold,
     so the end-point marker stays the brightest thing on the chart. */
  --chart-line: #93bbe9;
  --chart-grid: #2c3a4b;
  --chart-label: #93a1b3;
  --chart-fill-strong: 0.22;
}

svg.t-chart { width: 100%; height: auto; display: block; overflow: visible; }
.t-chart__grid line { stroke: var(--chart-grid); stroke-width: 1; }
.t-chart__base { stroke: var(--chart-grid); stroke-width: 1; }
.t-chart__lab {
  fill: var(--chart-label);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
}
.t-chart__area { stroke: none; }
.t-chart__g0 { stop-color: var(--chart-line); stop-opacity: var(--chart-fill-strong); }
.t-chart__g1 { stop-color: var(--chart-line); stop-opacity: 0; }
.t-chart__line {
  fill: none;
  stroke: var(--chart-line);
  stroke-width: 2.2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.t-chart__dot { fill: var(--chart-dot); stroke: var(--card); stroke-width: 2; }

@media (prefers-reduced-motion: no-preference) {
  /* The line draws itself once, on results. Length is set inline by the
     script because only it knows the path length. */
  .t-chart__line {
    stroke-dasharray: var(--len);
    stroke-dashoffset: var(--len);
    animation: chartdraw 900ms var(--ease, cubic-bezier(0.22, 1, 0.36, 1)) forwards;
  }
  .t-chart__dot { animation: chartdot 300ms 820ms backwards; }
  @keyframes chartdraw { to { stroke-dashoffset: 0; } }
  @keyframes chartdot { from { opacity: 0; transform: scale(0.2); transform-origin: center; } }
}

@media print {
  .t-chart__line { stroke: #000; }
  .t-chart__lab { fill: #333; }
}

/* ============================================================
   INVALID FIELDS
   One appearance for a wrong answer, everywhere on the site, the
   contact form and the four calculators had drifted into their own
   conventions. Colour alone would fail anybody who cannot see red,
   so the ring changes weight as well as hue, and the message that
   goes with it always names the field in words.
   ============================================================ */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--neg) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--neg) 16%, transparent) !important;
}
input[aria-invalid="true"]:focus,
select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--neg) 30%, transparent) !important;
}

/* ============================================================
   DATA MARKS

   The inventory of every shape on this site that is colour-as-
   information rather than decoration: a segment of a stacked bar, the
   legend dot that names it, the quiz progress bar, and the three-band
   scale the quiz result points at.

   One list on purpose. These live on four different pages and two of
   them are quiz-only, so the tidy instinct is to style each where it
   is used, which is how the list stops existing and the next chart
   somebody adds gets whatever colour looked nice that afternoon. The
   thing worth keeping in one place is not the declaration, it is the
   census.

   None of them can be checked by reading a stylesheet. The bar and
   the dot take their fill from script, because the fill is the datum.
   The quiz shapes are worse: their colour IS in here, but a gradient
   has no backgroundColor to read, so a probe looking for a fill finds
   rgba(0,0,0,0) and moves on. Neither kind is text. That is how a
   navy segment sat on a navy panel at 1.14:1, and how two thirds of
   the quiz's result meter sat at 1.01:1, invisible, on the graphic
   the entire quiz exists to produce, while every automated check on
   this site reported green.

   The hairline is the general answer. It gives a mark a defined edge
   whatever ends up filling it, which matters most for the brand gold:
   gold is 2.25:1 on a white card, and the fix cannot be "use a darker
   gold" because gold's neighbour in the bar is green, and darkening
   gold to clear the panel would have collapsed gold-against-green
   from 2.2:1 to 1.3:1. Trading one invisible boundary for another is
   not a fix.

   It answers the unlit case too, which is the half nobody thinks to
   check. An empty progress track and an unreached band are both
   saying something (how far is left, what the other outcomes were)
   and both were drawn in the faintest tint the palette has. A reader
   who cannot see the groove cannot see that the bar is a proportion.

   Inset rather than a border on purpose: these segments are sized in
   percentages that have to add to a hundred, a dot is ten pixels
   wide, and the progress track is six pixels tall. A border would
   change all three.

   It also decides what happens on paper, and the two halves of this
   list want opposite things there. Every print dialog defaults
   background graphics OFF, and an inset shadow is a background, so
   the bar segments and the legend dots lose their edge along with
   their fill, which is right: an outline around a colour that is no
   longer there describes nothing, and the breakdown list underneath
   prints every figure in words anyway. The quiz meter has no such
   list. Its three bands ARE the result, so the print sheet re-draws
   them with a real border and fills the one the reader landed in;
   that rule lives in the print section with the other paper
   decisions. The edge here and the border there are not duplicates:
   one is for a screen that shows colour and one is for a page that
   may not.

   One rule that belongs to this idea is not here: the quiz's lit
   band sets box-shadow itself, to carry a glow, at a specificity this
   file cannot reach from outside. It is amended in leadership-quiz.html
   next to the glow it has to keep, which is the honest place for it.
   ============================================================ */
.stackbar span,
.brk .t-dot,
.track,
.zone { box-shadow: inset 0 0 0 1px var(--data-edge); }

/* ============================================================
   SHARE BAR
   Sits at the foot of a result. Two things a person actually
   wants once a calculator has told them something: keep it, and
   show it to the one other person who has a stake in the number.
   The link carries the inputs in its fragment, so "keep it" costs
   no account and no server, and the note says so, because a
   money tool that is quiet about where your numbers go has not
   earned the typing.
   ============================================================ */
.t-share {
  margin: 26px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
}
.t-share__btn {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink-accent);
  background: transparent;
  border: 1px solid var(--rule-strong, var(--rule));
  border-radius: 999px;
  padding: 9px 16px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease),
    color 0.25s var(--ease), transform 0.25s var(--ease);
}
.t-share__btn:hover {
  background: var(--gold-soft);
  border-color: var(--gold);
  transform: translateY(-1px);
}
.t-share__btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}
.t-share__btn.is-copied {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
  transform: none;
}
.t-share__note {
  flex: 1 1 240px;
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--mid);
}
/* Only shown when the page was opened from a shared link, the one
   moment a visitor needs telling that these are not fresh numbers. */
.t-share__restored { display: none; }
:root[data-from-link] .t-share__restored {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 1 1 100%;
  order: -1;
  margin: 0 0 4px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--finances-deep, var(--mid));
}
.t-share__restored::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--finances, currentColor);
  flex: none;
}

/* ============================================================
   TOOL PRINT
   A budget is something people put on a fridge. Printing one of
   these pages should produce the answer on paper, not the form
   that produced it, not the navigation, and not four cards
   inviting you to try the other calculators.
   ============================================================ */
@media print {
  #main .t-card:not(.results),
  #main .cta-row,
  #main .crumbs,
  #main .toolcross,
  #main .toolnews,
  #main .t-share,
  #main .t-chips,
  #main .t-seg,
  #main .t-hint,
  #main .calc-btn,
  #main .retake,
  #main .quiz-progress,
  #main .halo,
  /* The cross-links are the same cross-sell as .toolcross, one level in:
     two cards at the foot of the result pointing at the other calculators.
     They were missed the first time because they sit inside the results
     panel rather than after it, and the panel is the thing print keeps. */
  #main .xlinks,
  #main .halo2 { display: none !important; }

  /* The results panel is the document now: no card chrome, full width.
     overflow has to be named explicitly, the card clips to its own box on
     screen so the halo behind the heading stays inside the rounded corner,
     and with the padding stripped to zero that same clip was shaving the
     first letter off the line underneath. */
  #main .grid { display: block !important; }
  #main .quizwrap { max-width: none !important; padding: 0 !important; }
  #main .t-card.results,
  #main #results {
    display: block !important;
    background: #fff !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
    overflow: visible !important;
  }
  /* Marked !important because the rule below it lost a tie it never
     reported losing. Every tool page carries its own layout in a <style>
     block in its head, and those blocks spell the selector exactly as this
     one does, `#main .t-hero`, `#main .grid`. Equal specificity, and a
     <style> element in the document beats a linked stylesheet, so for as
     long as this rule has existed it has been overruled: fifty-six pixels
     of hero air and sixty-four of grid padding printed on every sheet while
     the stylesheet said padding: 0. Nothing reports a specificity tie;
     the declaration is simply not there in the computed style, which reads
     exactly like a rule nobody wrote. Screen air is the first thing paper
     should lose: the page margin already provides the frame. */
  #main .t-hero { padding: 0 !important; margin-bottom: 14px !important;
                  max-width: none !important; }
  #main .grid, #main .grid4 { padding: 0 !important; }
  #main .t-hero .lede { display: none; }
  #main .t-hero h1 { font-size: 26pt; margin: 0; }
  #main .t-chart { max-width: 460px; }

  /* Paper is not a phone. Letter at 16mm margins leaves a 695px column, and
     695 is under 880, so every `@media (max-width: 880px)` block on these
     pages fires when the sheet is composed, and the printer has been handed
     the layout written for a handset. On the debt planner that meant four
     summary tiles stacked two-up, and the payoff order and its chart in one
     column with the chart pushed underneath: three hundred and forty pixels
     of paper spent accommodating a narrowness paper does not have. The
     handset rules are a response to a viewport that can only be scrolled;
     a sheet is fixed, wide, and taken in whole. It gets the wide layout. */
  #main .t-stats { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
  #main .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important; }

  /* Card padding is a screen value: on screen it buys separation between
     panels that share a scrolling field, and it is generous because there
     is no cost to being generous with pixels. On paper the border already
     does the separating and every millimetre inside a box is a millimetre
     the sheet has to find somewhere. Cut, not removed, a figure jammed
     against a rule reads as a mistake.

     What this cannot fix, and should not try to: the payoff order has one
     line per debt, so this sheet is as long as the reader's situation is
     complicated. Two debts fit comfortably; six will take a second page,
     and that is the honest answer rather than a failure. The break seams
     above make sure it divides between steps when it does. */
  #main .t-panel { padding: 15px !important; }
  #main .stat { padding: 13px !important; }
  #main .t-stats { margin-bottom: 16px !important; }

  /* Where a printed plan is allowed to break: between its parts, never
     through one. The panel holding all of them is deliberately not on this
     list, it is two pages tall, so asking it not to break just moved the
     break to the worst possible place, in front of the whole thing.
     The seams are the headline block, the summary figures, the chart, the
     colour breakdown, and any one step of the payoff order. A month of the
     plan split across a page turn is a month somebody misreads. */
  #main .res-top,
  #main .t-stats,
  #main .t-chart,
  #main .brk,
  #main ol.order li { break-inside: avoid; }

  /* The result is the headline of the sheet, so it is set as one: the panel
     is gone, the number is the biggest ink on the page, and a rule carries
     the weight the navy fill used to. */
  /* The radius and the clip are both properties of a navy panel, and the
     navy panel is gone. Left in place they each did visible damage. The
     corner radius survived onto a box whose only remaining edge is the rule
     under the number, so on the debt sheet that rule printed as a shallow
     smile, a hairline that swept upward at both ends for no reason a reader
     could name. And `overflow: hidden`, there to keep the gold halos inside
     the rounded corner, went on clipping after the padding was stripped to
     zero: the first line of the panel now starts at the box's own left edge,
     which is inside the corner arc, so "Left to spend" printed as "_eft to
     spend". One character, on the line that says what the number means. */
  #main .res-top { padding: 0 0 16px !important; margin: 0 0 22px !important;
                   border-bottom: 2px solid #000;
                   border-radius: 0 !important; overflow: visible !important; }
  #main .res-big, #main .res-date { color: #000 !important; }
  #main .res-cap, #main .res-sub { color: #333 !important; }

  /* The number, and what it is not, on the line directly under it.

     This sentence used to open with the address as well, and a companion
     rule switched off the site's generic provenance band so the address
     would not print twice. Both halves of that arrangement are gone. The
     address now rides in the footer row on every sheet, at no cost, so this
     line does not need to carry it. And the suppression was not doing what
     it said: it was spelled `#main::after`, and every page on this site
     spells its main element `<main id="main">`, so a rule written to quiet
     four calculator sheets quieted all thirteen pages, and the generic band
     it was hiding had never reached paper anywhere.

     What survives is the half that could not have lived in the footer. A
     reader holding a debt schedule is looking at the number, and the caveat
     has to be where the eye already is rather than four inches below in
     seven-point type. The footer's disclaimer says the same thing at length
     and stays; this is not a duplicate of it, it is a placement. */
  #main .results::after,
  #main #results::after {
    content: "Figures here are hypothetical illustrations, not financial advice.";
    display: block;
    margin-top: 14px;
    padding-top: 8px;
    border-top: 1px solid #bbb;
    font-size: 8.5pt;
    letter-spacing: 0.02em;
    color: #333;
  }

  /* The quiz prints a gear, not a number.

     It shares the results panel with the three calculators, so it inherited
     their caveat, and a sheet that says "You're in Neutral. Score 0 of 24"
     was carrying the words "not financial advice" underneath it. That was
     always wrong; it was merely less visible while the sentence also carried
     an address, so half of it applied. Scoped by the quiz's own container
     rather than by a page name, because what makes this sheet different is
     that it reports a self-assessment, and .quizwrap is where that lives. */
  #main .quizwrap .results::after,
  #main .quizwrap #results::after {
    content: "This is a self-assessment of one moment at work, not a rating of you.";
  }

  /* ---- the quiz result -------------------------------------------
     The result screen has a "Print or save as PDF" button on it, so
     this is a feature the page advertises rather than an edge case.
     Two things had to be fixed for it to keep that promise. The card
     is a .t-card without .results on the intro and question screens,
     so the rule above hid all three and printing produced a sheet
     with nothing on it but a footer. And the meter said which gear
     you are in entirely through painted fills, which is the one thing
     a printer will not do, so it says it in borders and weight
     instead, and reads the same in black ink. */
  #main .screen.active .t-card { display: block !important; }
  #main .booknote { break-before: avoid-page; }

  #main .meter-track .zone {
    background: none !important;
    border: 1px solid #999;
    height: 12px;
  }
  #main .meter[data-band="park"] .zone-park,
  #main .meter[data-band="neutral"] .zone-neutral,
  #main .meter[data-band="drive"] .zone-drive {
    border: 3px solid #000;
  }
  #main .meter-labels .ml { color: #666 !important; }
  #main .meter[data-band="park"] .ml-park,
  #main .meter[data-band="neutral"] .ml-neutral,
  #main .meter[data-band="drive"] .ml-drive {
    color: #000 !important; font-weight: 700; text-decoration: underline;
  }
  #main .marker-flag {
    color: #000 !important; border: 1.5px solid #000; font-weight: 700;
  }
  #main .marker-stem { width: 0; border-left: 2px solid #000; }
  #main .marker-tip { border-top-color: #000; }
}

/* ============================================================
   TOOL PAGE TAIL
   Every calculator ends the same way: a rail to the other tools,
   then the newsletter. A visitor who arrived from a search result
   should never hit a dead end at the bottom of a calculator.
   ============================================================ */
.toolcross { margin: 64px 0 0; }
.toolcross > h2 {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
  font-weight: 500;
  margin: 0 0 18px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.toolcross > h2::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}
.toolcross__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
}
.toolcross__card {
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 22px 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: var(--card);
  text-decoration: none;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.toolcross__card:hover { transform: translateY(-3px); border-color: var(--gold); box-shadow: var(--shadow-2); }
.toolcross__card h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink-accent);
  margin: 0;
}
.toolcross__card p { font-size: 15.5px; line-height: 1.5; color: var(--mid); margin: 0; }
.toolcross__go {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-top: 6px;
}

/* ------------------------------------------------------------------
   TOOL PAGE HERO
   Lived in four page-scoped <style> blocks, which is three copies too
   many of a rule that has to match, and they had already drifted:
   three left-aligned and one centred, three with one gold rule and one
   with two, three led by a numeral and one by a glyph.

   The numeral was the deeper mistake. Everywhere else on the site an
   eyebrow numeral means "section N of this page", and it counts from 01,
   but a calculator's numbered sequence already belongs to its form
   steps (01 YOUR INCOME, 02 PAY YOURSELF FIRST, 03 BILLS & ESSENTIALS),
   so a numbered hero collides with the only numbers on the page that
   mean anything. That is how they ended up reading 01, 04 and $: three
   pages guessing at a number none of them could correctly have.

   So: content pages number their sections, tool pages mark their hero
   with the tool's own glyph. The quiz already did this and was right.

   Selectors carry `#main` to match the specificity the page blocks had,
   so a page keeps its responsive override without an `!important`.
   ------------------------------------------------------------------ */
#main .t-hero { padding: 56px 0 26px; max-width: 760px; }
#main .t-eyebrow {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: 2.2px;
  text-transform: uppercase; color: var(--ink-accent);
  display: flex; align-items: center; gap: 11px;
}
#main .t-eyebrow .t-glyph { color: var(--gold); display: inline-flex; flex: none; }
#main .t-eyebrow .t-glyph svg { width: 16px; height: 16px; display: block; }
#main .t-eyebrow::after {
  content: ""; height: 1px; flex: 1; max-width: 60px;
  background: var(--gold); opacity: .5;
}

/* Newsletter band that closes each tool page */
.toolnews {
  margin: 56px 0 0;
  background: var(--navy);
  border-radius: var(--radius-lg);
  padding: clamp(30px, 5vw, 52px);
  position: relative;
  overflow: hidden;
}
.toolnews::after {
  content: "";
  position: absolute;
  inset: auto -60px -110px auto;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(201,169,97,0.18), transparent 68%);
  pointer-events: none;
}
.toolnews__inner { position: relative; max-width: 560px; }
.toolnews h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(26px, 3.6vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--on-navy-strong);
  margin: 12px 0 12px;
}
.toolnews p { color: var(--on-navy); font-size: 16px; line-height: 1.6; margin: 0 0 22px; }
.toolnews .news__fine { font-size: 13.5px; color: var(--mid); margin: 14px 0 0; }
/* the site-wide band gets this gap from `.news { gap: 14px }`; here the form is a
   direct child of the panel, so the acknowledgement has to carry its own. */
.toolnews .news__ok { margin: 14px 0 0; }
.eyebrow-mono {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0;
}
.toolnews .news__form { max-width: 470px; }
.toolnews .news__form input[type="email"] {
  background: rgba(255,255,255,0.07);
  border-color: rgba(255,255,255,0.22);
  color: #fff;
}
.toolnews .news__form input[type="email"]::placeholder { color: rgba(255,255,255,0.55); }
.toolnews .news__form input[type="email"]:focus {
  outline: none;
  border-color: var(--focus-ring);
  box-shadow: 0 0 0 3px var(--focus-halo);
}
.toolnews .btn--primary { background: var(--gold); color: #10192a; border-color: var(--gold); font-weight: 700; }
.toolnews .btn--primary:hover { background: var(--gold-soft); border-color: var(--gold-soft); color: #10192a; }
:root[data-theme="dark"] .toolnews .btn--primary:hover { background: #e7c98a; border-color: #e7c98a; }

/* Screen-reader only */
.vh {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Toast used for "link copied" confirmations */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 16px);
  background: var(--navy); color: #fff; padding: 12px 20px; border-radius: 999px;
  font-size: 15px; font-weight: 500; box-shadow: var(--shadow-3);
  opacity: 0; pointer-events: none; transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  z-index: 90;
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }
:root[data-theme="dark"] .toast { background: var(--gold); color: #10192a; }
