:root {
  --navy: #123B54;
  --navy-deep: #0C2C3F;
  --navy-panel: #184460;
  /* gold updated site-wide to pair with the new bright azure (medallion
     pairing, direct instruction) - soft/bright keep the same lighter-step
     relationship the old E0B94A trio had, just recomputed from this base. */
  --gold: #F2C94C;
  --gold-soft: #F5D573;
  --gold-bright: #FCE066;
  /* the one dedicated role for gold sitting directly on the bright azure
     canvas (not on a card): the kicker label and the cover's "Azure"
     highlight box. Was two separately-trialed hexes (#FFEB80/#FFDE59);
     tested merging them and one value reads fine in both a thin-text and a
     solid-fill context, so this replaces both rather than adding a fourth
     gold to the scale. Kept distinct from --gold-bright, which already
     drives ~10 unrelated tab hover/active states. */
  --gold-on-azure: #FFEB80;
  /* the site's one blue accent/link color, used for both the slide canvas
     background and every text/border/link role that used to reference the
     old muted teal --azure (#2E8B9A) - retired site-wide so there's a
     single considered blue rather than two unrelated ones. */
  --azure-bright: #1E6FD9;
  /* the slide canvas's own gradient stops - deliberately less saturated
     than the accent color above (~20%, luminance-matched so it's not
     darker/lighter, just calmer). Pure-saturation azure behind large
     blocks of white reading text was causing eye strain (chromatic
     aberration between warm text and a fully-saturated blue field, not
     just a contrast-ratio problem) - mocked up as an Artifact and
     confirmed before applying. Scoped to the .slide/.grid-overlay
     backgrounds only; --azure-bright itself (the link/accent color used
     everywhere else) is untouched. */
  --azure-bright-light: #3F80CE;
  --azure-bright-mid: #2E6EC3;
  --azure-bright-deep: #1D417A;
  /* deck card fill: frosted glass - a translucent white lift off the
     bright azure canvas rather than any pigment of its own (mocked up as
     an Artifact against two blue alternatives, chosen because navy-derived
     fills kept reading as "leftover navy" no matter how the hue was
     adjusted). Scoped to the deck's own card-style components below;
     --navy-panel is untouched and still drives blog/legal/admin surfaces. */
  --deck-card-fill: rgba(255,255,255,0.13);
  --deck-card-border: rgba(255,255,255,0.28);
  --ink: #F4F1E8;
  /* warm ivory for flowing body copy (paragraphs/sentences), site-wide -
     split from --ink deliberately: headlines/titles/labels stay true
     white (large, short, bold text tolerates it fine), but pure white
     across longer reading text on a saturated background was the other
     half of the eye-strain problem the desaturated gradient above
     addresses - mocked up as an Artifact and confirmed before applying. */
  --ink-soft: #EDE3CE;
  --ink-dim: rgba(244, 241, 232, 0.68);
  --ink-faint: rgba(244, 241, 232, 0.38);
  --line: rgba(244, 241, 232, 0.14);
  --serif: "Playfair Display", Georgia, serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
  /* fixed reference canvas the whole slide is designed at, then scaled as one
     unit to fit the viewport (desktop/tablet only — see the theatre-mode
     block below) so border/text/spacing stay in identical proportion on
     every screen, like a real pitch-deck slide rather than a reflowing page */
  --slide-w: 1280px;
  --slide-h: 720px;
  /* 100px, not a small gutter: the fixed bottom chrome (slide counter,
     bottom-controls toolbar, version stamp) sits ~65-76px tall above the
     viewport's bottom edge, outside the card entirely. The card needs at
     least that much clearance on every side or it visually overlaps them. */
  --stage-margin: 100px;
  /* floor on the theatre-mode scale factor below: the min(1.4, ...)
     ceiling formula has no lower bound on its own, so a short/small
     window (a real laptop after browser chrome) could shrink the deck
     well past 75% of its designed size - read as "too small." 0.85 keeps
     it recognizably full-size and makes the page scroll instead of
     shrinking further. NOTE: this constant and --stage-margin together
     must satisfy slide-w*--stage-min-scale + 2*--stage-margin > slide-w
     (currently 1280*0.85+200=1288>1280, only an 8px margin) - if either
     constant changes, re-check this inequality, since it's what keeps the
     flex container from reverting to content-driven growth off .slide's
     raw unscaled box (the exact bug this whole mechanism works around). */
  --stage-min-scale: 0.85;
  /* real rendered height of the sticky .blog-header (measured ~86px at its
     normal 1.5rem vertical padding + logo line-height), rounded up a bit for
     safety. Anything that sticks its own top edge to the viewport on a
     non-deck page (sidebars, etc.) needs to offset by this, or it sticks
     underneath/behind the header instead of just below it. */
  --sticky-header-h: 90px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* medallion watermark position, bottom-right by default - override per
     page (inline style on <body>) wherever that page's own layout leaves a
     different corner emptier, so it never sits under copy or UI. */
  --medallion-pos: 94% 92%;
  /* bright-azure canvas, matching the deck's .slide fill — only takes
     effect on non-deck pages, since body:has(main.slide) below overrides
     this for the pitch deck itself.
     Constellation + medallion layers: the exact same brand-assets/patterns/
     *.svg files the deck's own .slide canvas uses (see that rule) - one
     shared network reused everywhere, not a different one generated per
     page, so every surface in the site reads as one continuous scene. No
     inset hairline frame here (that's scoped to .slide, a bounded card) -
     there's no card to frame around a whole scrollable page. */
  background-image:
    url("/brand-assets/patterns/constellation-network.svg"),
    url("/brand-assets/patterns/medallion-mark.svg"),
    radial-gradient(ellipse 60% 45% at 15% -10%, rgba(255, 255, 255, 0.09), transparent 60%),
    radial-gradient(ellipse 55% 50% at 105% 115%, rgba(242, 201, 76, 0.09), transparent 60%),
    linear-gradient(155deg, var(--azure-bright-light) 0%, var(--azure-bright-mid) 45%, var(--azure-bright-deep) 100%);
  background-position: -6% -8%, var(--medallion-pos), 0 0, 0 0, 0 0;
  background-size: 135% 135%, 34%, auto, auto, auto;
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--sans);
  min-height: 100%;
}

/* cross-document crossfade, preserving the deck feel between real pages */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

::selection { background: var(--gold); color: var(--navy-deep); }

button {
  font-family: inherit;
  cursor: pointer;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--gold);
  color: var(--navy-deep);
  padding: 0.75rem 1.25rem;
  /* 500, not 600: this was the only thing on the site pulling Inter SemiBold,
     an entire extra font file for a link that is off-screen until tabbed to */
  font-weight: 500;
  z-index: 999;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

/* ---------- progress bar ---------- */
.progress-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: rgba(244,241,232,0.08);
  z-index: 60;
}
.progress-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--azure-bright), var(--gold));
  width: 11.11%;
  transition: width 0.5s cubic-bezier(.4,0,.2,1);
}

/* ---------- page ---------- */
/* each page is one full-viewport panel; it grows if its content needs more room */
.slide {
  position: relative;
  width: 100%;
  min-height: 100vh;
  display: flex;
  /* flex-start, not center: with vertical centering, the kicker's on-screen
     position shifted from slide to slide depending on how tall that
     slide's content was — a short slide (e.g. consult.html) centered its
     kicker much lower than a tall one. Top-aligning makes the kicker sit
     at the same anchor point (right after the top padding) on every
     slide. The cover is the deliberate exception — .slide-cover overrides
     this back to centered, since it's a title card, not a content slide,
     and its layout wasn't designed around a top-anchored kicker. */
  align-items: flex-start;
  padding: clamp(2rem, 6vw, 6rem);
  padding-bottom: clamp(6rem, 12vw, 8rem);
}

.slide-inner {
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
}

/* ---------- theatre mode: every slide as a framed card on a dim stage ---------- */
/* "screen and" is load-bearing here too, same reason as the mobile breakpoint
   below: a live page could still be sent to a real printer, and this frame/
   stage treatment has no meaning on paper. */
@media screen {
  body:has(main.slide) {
    position: relative;
    min-height: 100vh;
    background: radial-gradient(circle at center, var(--navy-panel) 0%, var(--navy) 40%, var(--navy-deep) 75%, #0a2338 100%);
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /* ambient glow: fixed to the viewport (not absolute to the document) so it
     reads as a light source in the room rather than scrolling away on the
     handful of slides taller than one screen. Paints behind .slide for free —
     no z-index needed, it's simply earlier in DOM order. */
  body:has(main.slide)::before {
    content: "";
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(80vw, 1300px);
    aspect-ratio: 16 / 9;
    background: radial-gradient(ellipse at center, rgba(242,201,76, 0.16) 0%, rgba(46, 139, 154, 0.14) 45%, transparent 75%);
    filter: blur(70px);
    pointer-events: none;
  }
  .slide {
    /* medallion watermark position — bottom-right by default, overridden per
       page (inline on <main class="slide">) wherever that page's own layout
       leaves a different corner emptier. See PATTERNS.md-equivalent comment
       on html,body below for the sitewide rationale. */
    --medallion-pos: 90% 88%;
    /* subtle corner light + diagonal depth, instead of flat azure — reads as
       a lit surface rather than a solid-fill rectangle. Kept faint enough
       that body copy contrast is unaffected. Swapped from navy to the new
       bright azure per direct approval this session (mocked up first as a
       standalone Artifact); cards/components elsewhere are unchanged, this
       is the slide canvas fill only.
       Constellation + medallion layers reuse the exact same two brand-assets
       /patterns/*.svg files as html,body below (see that rule's comment for
       why one shared network, not a per-page one) — scaled/positioned
       slightly differently here since this is a bounded card, not the full
       viewport. */
    background-image:
      url("/brand-assets/patterns/constellation-network.svg"),
      url("/brand-assets/patterns/medallion-mark.svg"),
      radial-gradient(ellipse 60% 45% at 15% -10%, rgba(255, 255, 255, 0.09), transparent 60%),
      radial-gradient(ellipse 55% 50% at 105% 115%, rgba(242, 201, 76, 0.09), transparent 60%),
      linear-gradient(155deg, var(--azure-bright-light) 0%, var(--azure-bright-mid) 45%, var(--azure-bright-deep) 100%);
    background-position: -6% -8%, var(--medallion-pos), 0 0, 0 0, 0 0;
    background-size: 122% 122%, 44%, auto, auto, auto;
    background-repeat: no-repeat;
    border: 1px solid var(--line);
    border-radius: 12px;
    box-shadow:
      /* inset vignette: gently darkens toward the edges, drawing the eye
         back to the center content the way a lit stage/photo mat would */
      inset 0 0 110px rgba(0, 0, 0, 0.35),
      0 8px 24px rgba(0, 0, 0, 0.55),
      0 25px 60px rgba(20, 60, 90, 0.4),
      0 55px 120px rgba(242,201,76, 0.12);
  }
  /* inset hairline frame — a mat within a frame, echoing fine letterhead.
     Only on .slide (a bounded card); the non-deck background below has no
     card to frame, so it skips this. */
  .slide::before {
    content: "";
    position: absolute;
    inset: 14px;
    border: 1px solid rgba(242,201,76,0.35);
    border-radius: 8px;
    pointer-events: none;
    /* no z-index: ::before is first in document order, so with z-index:auto
       it paints before (behind) the slide's real static-position content -
       a positive z-index here would instead jump it above the kicker/
       headline/cards, which is wrong for a background-adjacent decoration. */
  }
  /* fine film-grain texture — the classic "premium print" cue. A generated
     noise tile via SVG feTurbulence, desaturated, layered at near-zero
     opacity with a blend mode so it reads as texture, not visible speckling. */
  .slide::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    opacity: 0.035;
    mix-blend-mode: overlay;
    pointer-events: none;
  }
}

/* fixed-canvas scaling: every slide is designed at one reference size
   (--slide-w x --slide-h) and scaled as a single unit to fit the viewport,
   so border/text/spacing stay in identical proportion everywhere — like a
   real pitch-deck slide, not a page that reflows per browser/resolution.
   Desktop/tablet only; mobile keeps its own reflowed layout (below). */
@media screen and (min-width: 769px) {
  body:has(main.slide) {
    /* --stage-scale is the single source of truth for the theatre-mode
       scale factor - computed once here, referenced by .slide's transform
       below, so this rule's sizing and .slide's paint can never drift out
       of sync. The min(1.4, ...) ceiling is unchanged from before; the new
       max(--stage-min-scale, ...) floors the shrink at 85% of designed
       size instead of letting a short window shrink it arbitrarily. */
    --stage-scale: max(
      var(--stage-min-scale),
      min(
        1.4,
        calc((100vw - 2 * var(--stage-margin)) / var(--slide-w)),
        calc((100vh - 2 * var(--stage-margin)) / var(--slide-h))
      )
    );
    /* min-height/min-width, not a hard height: a flex container's auto
       size is content-driven, so it WILL grow to fit .slide's raw,
       untransformed 1280x720 layout box if allowed to (that was the
       original bug this code fixed with a hard height:100vh). Flooring
       the container instead at the *scaled* footprint (--stage-scale *
       slide-w/h, plus the stage margin on both sides) keeps the container
       exactly big enough to hold the scaled slide with correct margins,
       whether or not that's bigger than 100vh/100vw - and because that
       computed floor is always bigger than .slide's raw 1280x720 box (see
       the --stage-min-scale comment in :root), the container never grows
       past this value on its own, so centering math stays exact. When the
       floor pushes past the real viewport, overflow:auto (was hidden)
       lets the page scroll to reveal the rest instead of clipping it. */
    min-height: max(100vh, calc(var(--slide-h) * var(--stage-scale) + 2 * var(--stage-margin)));
    min-width: max(100vw, calc(var(--slide-w) * var(--stage-scale) + 2 * var(--stage-margin)));
    overflow: auto;
  }
  .slide {
    width: var(--slide-w);
    height: var(--slide-h);
    min-height: 0;
    margin: 0;
    /* body (the flex container) can be narrower than 1280px, and a flex item
       shrinks below its specified width by default (flex-shrink:1) to fit —
       silently undoing the fixed canvas and making width:var(--slide-w)
       above a no-op at any viewport narrower than the canvas. This was the
       actual source of every inconsistency chased today: text wrapping,
       overflow measurements, all of it assumed .slide was really 1280px
       wide, but it was quietly being squashed to the real viewport width. */
    flex-shrink: 0;
    /* fixed px, not the base rule's vw-based padding: that padding (especially
       the big padding-bottom) was sized to clear the old in-flow bottom
       toolbar on a full-viewport page. The toolbar now lives outside the card
       entirely, and vw-based padding was scaling with the *real* browser
       width rather than this fixed canvas — on a normal ~1920px monitor it
       clamped to its max (6rem/8rem = 96px/128px), eating ~224px of the
       fixed 720px canvas and pushing several slides' content out the top. */
    padding: 48px 64px 56px;
    transform: scale(var(--stage-scale));
    transform-origin: center center;
  }

  /* the outer .slide transform already scales border/text/spacing together
     as one unit — so nothing inside it should ALSO respond to the real
     viewport via vw. Every vw-based clamp() below silently resized text with
     the visitor's actual screen width (e.g. .headline rendered 44px at a
     960px-wide window but 54px at 1920px), which is exactly what broke
     founder-vs-lawyer.html on a normal desktop monitor even after the fixed-
     canvas sizing above: bigger real-viewport text needs more lines, which
     overflows a canvas that's supposed to be constant.
     Values below are each clamp()'s previously-computed size at a ~960px
     viewport (the width the original deck was mostly authored/tested
     against), not the clamp's arbitrary large-screen cap — the cap was
     tuned for an unbounded-height page, not this 720px canvas, and using it
     verbatim still overflowed. ".slide X" (specificity 0,2,0), not "X"
     alone: a same-specificity rule placed earlier in the file loses to the
     original later in the cascade regardless of the media query, so these
     need to out-rank it, not just out-position it. */
  .slide .headline,
  .slide .headline-small {
    font-size: 2.76rem;
    max-width: none;
    white-space: nowrap;
  }
  .slide .lede { font-size: 1.05rem; }
  .slide .lede-italic { font-size: 0.95rem; }
  .slide .cf-thesis { font-size: 1.02rem; }
  .slide .svc-panel-blurb { font-size: 0.92rem; }
  .slide .tier-price { font-size: 1.4rem; }
  .slide .wordmark { font-size: 5.4rem; }
  .slide .subtitle { font-size: 1.44rem; }

  /* the tall slides were scaled down uniformly, which shrank width along with
     height — leaving unused navy down both sides of an already-small card.
     Widening each toward the canvas's real available width (1280 minus the
     48px/64px/56px padding = 1152px) lets text/grids use that space instead,
     which for non-aspect-locked content (cards, paragraphs) also shortens
     the content and reduces how much vertical scale-down is still needed.
     "main.X" (specificity 0,2,1), not "X" alone: needs to out-rank the base
     max-width rules elsewhere in the file, not just out-position them. */
  main.slide-tiers .slide-inner          { max-width: 1140px; }
  main.slide-clientfit .slide-inner      { max-width: 1140px; }
  main.slide-appendix .slide-inner       { max-width: 900px; }
  main.slide-diagram .slide-inner        { max-width: 1140px; }
  main.slide-practice-areas .slide-inner { max-width: 1140px; }

  /* the consolidated practice-areas slide carries an outer practice-tab row
     on top of everything every single practice slide already had, and its
     height is set by whichever area+stage combination is tallest across
     all 6 — near-certain to need the same treatment as the other tall
     slides below. Re-measure against real content rather than trusting
     this starting guess.
     "top center", not "center center": .slide-inner's LAYOUT box (which a
     transform never shrinks) is its full pre-scale height, taller than the
     visible card. With .slide top-aligning its flex children (the
     kicker-anchor change above), that oversized box starts flush at the
     top padding — but centering the shrink around the box's own middle
     still anchors the shrink to the middle of that tall invisible box, not
     to the visible top edge, which pushes content past the card's bottom.
     Shrinking from the top instead keeps the visible top edge fixed and
     lets the excess height collapse downward, where the flex-start
     alignment already expects it to be. */
  .slide-tiers .slide-inner,
  .slide-clientfit .slide-inner,
  .slide-appendix .slide-inner,
  .slide-fvl .slide-inner,
  .slide-practice-areas .slide-inner { transform-origin: top center; }
  .slide-tiers .slide-inner          { transform: scale(0.83); }
  .slide-clientfit .slide-inner      { transform: scale(0.94); }
  .slide-appendix .slide-inner       { transform: scale(0.97); }
  .slide-fvl .slide-inner            { transform: scale(1); }
  .slide-practice-areas .slide-inner { transform: scale(1); }

  /* founder-vs-lawyer.html: blurb + diagram side by side instead of stacked.
     Scoped to .slide-fvl only — practice-areas.html shares .svc-panel but
     uses a different (services/documents two-column) layout, not a
     blurb+SVG one. Putting these side by side uses the card's full width
     instead of a full-width diagram sitting alone above a mostly-empty-
     width blurb, and — because the diagram now renders at roughly the
     width of one column instead of the whole card — its height (fixed
     2.5:1 aspect ratio) drops enough that the panel row no longer needs
     the heavy scale-down above to fit the canvas. */
  .slide-fvl .svc-panel {
    display: flex;
    align-items: center;
    gap: 2rem;
  }
  .slide-fvl .svc-panel-blurb {
    flex: 0 0 clamp(260px, 30%, 340px);
    margin-bottom: 0;
    text-align: justify;
    text-justify: inter-word;
  }
  .slide-fvl .svc-panel svg {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* the kicker's vertical anchor (align-items: flex-start, above) still let
     its HORIZONTAL position drift slide to slide: .slide-inner is centered
     via max-width + margin:auto, and that max-width differs per slide type
     (900px default, 1140px for the diagram/tiers/practice-areas slides,
     900px for appendix, ...), so the kicker's left edge landed wherever
     that particular centering math put it. Pulling the kicker out of
     .slide-inner's flow entirely and pinning it to .slide itself — the
     same fixed spot on every slide, matching where it already naturally
     sits on founder-vs-lawyer.html (slide 3, the widest/least-inset
     content column) — makes it truly identical everywhere, independent of
     any slide's own reading-width choice. It also has a second effect,
     which is exactly right: a slide with its own extra content-scale
     (fractional-gc, clients, appendix, lifecycle, practice-areas) no
     longer shrinks the kicker along with everything else, since the
     kicker is no longer a descendant of the element being scaled — it
     renders at the same size everywhere too, not just the same position.
     Excludes .slide-cover and .slide-ask: both intentionally keep their
     kicker in-flow with the rest of their centered, title-card-style
     content (slide 10 was asked to mirror slide 1's positioning exactly). */
  main.slide:not(.slide-cover):not(.slide-ask) .kicker {
    position: absolute;
    top: 48px;
    left: 110px;
    margin: 0;
  }
  /* compensates for pulling the kicker out of flow: without this, whatever
     used to be the second child (the headline, or a tab row) would rise up
     to fill the gap the kicker left behind. margin-top (not padding-top)
     specifically — margin positions the box within .slide's flex layout
     *before* .slide-inner's own per-slide transform: scale is applied, so
     this 40px gap stays a constant 40px even on slides that separately
     shrink their own content; padding would have been shrunk along with
     everything else and the gap would vary slide to slide again. */
  main.slide:not(.slide-cover):not(.slide-ask) .slide-inner { margin-top: 40px; }

  /* slide 2 (problem-solution.html): .slide-inner's default max-width:900px
     centers it well clear of the kicker's fixed 110px inset, leaving a
     large gap between "02 — Problem / Solution" and the tab row/headline
     below it. Left-align .slide-inner to that same inset instead of
     centering it, and widen it to use the remaining space up to the
     card's padding edge — same width-usage principle as the other slides
     already widened this session, so the two-card-grids get more room
     rather than leaving an empty margin on the right to match the one
     that used to be on the left. */
  main.slide-problem-solution .slide-inner {
    margin-left: 46px;
    margin-right: 0;
    max-width: 1106px;
  }

  /* same left-align-to-kicker + fill-remaining-width treatment as slide 2,
     applied to most remaining content slides (3/4/5/6/9). Each already
     had its own max-width for a different reason (diagram/tiers/practice-
     tab room) — this keeps that width budget but shifts it flush with the
     kicker's 46px inset instead of centering it.
     .slide-tiers (the archived _fractional-gc.html slide, not part of the
     active 10-slide deck) and .slide-insights are deliberately NOT in this
     group: both cap .slide-inner well under the card's full width (1040px
     and 1060px respectively), and left-aligning a capped-width block reads
     as lopsided flush-left (a big empty gap on the right, or — as measured
     on insights.html — an even bigger gap on the left once the fixed 46px
     margin and the max-width cap fight each other) rather than a balanced
     block. Both keep the default centered .slide-inner instead — the
     kicker itself is independently pinned via position:absolute
     regardless, so it still sits at the shared anchor either way. */
  main.slide-fvl .slide-inner,
  main.slide-lifecycle .slide-inner,
  main.slide-practice-areas .slide-inner,
  main.slide-team .slide-inner,
  main.slide-clientfit .slide-inner,
  main.slide-appendix .slide-inner {
    margin-left: 46px;
    margin-right: 0;
    max-width: 1106px;
  }
  /* .slide-lifecycle/.slide-practice-areas/.slide-clientfit all carry their
     own extra scale-down (above) with transform-origin: top CENTER —
     anchored to the box's own horizontal middle, which is fine while the
     box is centered, but once left-aligned via margin-left, scaling from
     the center undoes that: the shrink pulls the visible left edge inward
     by half the width reduction instead of leaving it at the 46px inset.
     Re-anchoring to the box's own left edge keeps that edge fixed through
     the scale, so the margin-left above actually sticks. (.slide-tiers
     isn't touched — still centered, not part of this alignment change,
     and "top left" would shift its appearance. .slide-appendix DOES carry
     its own scale(0.97) — see above — so it needs this fix too.) */
  .slide-practice-areas .slide-inner,
  .slide-clientfit .slide-inner,
  .slide-appendix .slide-inner { transform-origin: top left; }


  /* slide 5 (practice-areas.html): .svc-tabs/.svc-panels both carry a
     left/right clamp() padding meant to clear the fixed nav arrows at
     narrow viewports (see the rule above their shared definition) — but
     that clearance is redundant here, since the kicker-anchor system
     already keeps every other element on this slide (kicker, headline,
     lede, outer area-tabs) inset from the arrows via the deck-wide 46px
     margin. The padding just pushed the inner stage-tab pills and the
     panel card 16px right of everything above them. Zeroing it for this
     slide only lines the stage tabs and panel card up with the kicker,
     headline, and area tabs above — and widens the card by the same
     16px on each side. */
  .slide-practice-areas .svc-tabs,
  .slide-practice-areas .svc-panels {
    padding-left: 0;
    padding-right: 0;
  }

  /* slide 10 (consult.html): mirrors the cover's positioning exactly —
     vertically centered, kicker back in its normal in-flow spot rather
     than pinned to the deck-wide anchor. */
  .slide-ask { align-items: center; }

}

.kicker {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-on-azure);
  margin: 0 0 1.5rem;
  /* the kicker sits directly on the slide's own background (not a card),
     and that background just brightened considerably (navy -> azure) - a
     thin dark stroke + soft shadow keeps the gold letterforms from
     vibrating against it. Dialed back from an earlier 0.5px/0.5-alpha pass
     that was muting the gold itself - picked by direct comparison against
     the real background this session. */
  -webkit-text-stroke: 0.25px rgba(8, 20, 45, 0.3);
  text-shadow: 0 1px 2px rgba(4, 12, 28, 0.3);
}

.headline {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  line-height: 1.15;
  margin: 0 0 1.25rem;
  color: var(--ink);
  max-width: 15ch;
  /* halo shadow, no stroke - mocked up against a hard stroke and a
     directional shadow (Artifact comparison this session) and chosen over
     both: an even, unoffset glow on all sides holds contrast against the
     gradient's lighter zones without ever touching the letterform itself,
     so serif details (thin strokes, terminals, counters) stay clean -
     fits the site's hairline-not-decoration language better than a
     visible stroke or an offset drop-shadow would. */
  text-shadow: 0 0 14px rgba(0,0,0,0.4), 0 2px 4px rgba(0,0,0,0.35);
}
.headline-small { font-size: clamp(1.7rem, 3.4vw, 2.4rem); max-width: none; }

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--ink-soft);
  max-width: 46ch;
  line-height: 1.6;
  margin: 0;
}

/* Arrows are drawn, not typed. The characters U+2190/U+2192 are absent from
   the latin subsets of Playfair, Inter and Plex Mono, so every arrow in the
   deck forced a fallback face - and the PDF export then embedded three whole
   extra fonts (Segoe UI, Segoe UI Semibold, Consolas) to render a handful of
   glyphs. An inline SVG inherits currentColor and costs nothing. */
.arr {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  vertical-align: -0.13em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.arr-l { transform: scaleX(-1); }

.explore-link {
  margin-top: 1.5rem;
  background: none;
  border: none;
  color: var(--gold-soft);
  font-size: 0.95rem;
  font-weight: 500;
  padding: 0.4rem 0;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.explore-link:hover, .explore-link:focus-visible {
  color: var(--gold);
  border-bottom-color: var(--gold);
}
.explore-link span { transition: transform 0.2s ease; }
.explore-link:hover span { transform: translateX(3px); }

/* ---------- slide 8 (team.html): founder profile ----------
   First pass (headline + lede + a 2x2 fact grid) used the same building
   blocks as every other content slide — a safe layout, but for a
   one-person team it read as generic rather than confident: small stat
   tiles for a solo practice draw attention to how few of them there are,
   and a name styled at the deck's default .headline size sat no larger
   than any section title elsewhere in the deck.
   Redesigned around a clear hierarchy instead — name treated as the
   biggest, most editorial type on the slide (bigger than the standard
   .headline scale, on purpose: this is the one slide in the deck where
   a person, not a concept, is the subject); credentials collapsed into a
   single quiet "at a glance" rail instead of four boxes competing for
   attention; and the positioning statement promoted to a genuine pull-
   quote — oversized quotation glyph, large serif italic — because for a
   solo practice the confident THESIS ("direct access, not a bench") is
   worth more real estate than another data point. */
.team-grid {
  display: flex;
  gap: 9.5rem;
  align-items: flex-start;
}
.team-photo {
  flex: 0 0 auto;
  width: 300px;
  height: 460px;
  margin: 0;
  border-radius: 6px;
  border: 1px solid var(--deck-card-border);
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  position: relative;
  cursor: pointer;
  user-select: none;
}
/* interactive trading card: two images layered, headshot in front by default,
   NFT offset behind. Click toggles which is in front. */
.card-headshot,
.card-nft {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.3s ease, z-index 0.3s ease;
}
.card-headshot {
  z-index: 2;
  transform: translateX(0) translateY(0);
}
.card-nft {
  z-index: 1;
  transform: translateX(20px) translateY(20px);
}
/* when flipped, swap z-index and positions */
.team-photo.flipped .card-headshot {
  z-index: 1;
  transform: translateX(-20px) translateY(-20px);
}
.team-photo.flipped .card-nft {
  z-index: 2;
  transform: translateX(0) translateY(0);
}
.card-placeholder {
  width: 100%;
  height: 100%;
  border-radius: 4px;
  /* no backdrop-filter here unlike the other glass cards - this one sits
     in a layered flip-card stack with the NFT card positioned directly
     behind it, so blurring "what's behind" smears the other card's art
     through instead of just softening the plain canvas. A slightly higher
     fill opacity keeps it reading as glass without the blur. */
  background: rgba(255,255,255,0.22);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--ink-faint);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.card-placeholder-headshot::before {
  content: "Headshot Image";
}
.card-placeholder-nft::before {
  content: "NFT Image";
}
/* real photo/art fills the same 100%x100% box the placeholder divs used,
   so no other .card-headshot/.card-nft positioning has to change once a
   real image replaces a placeholder. object-position biased toward the
   top since these are portrait-cropped from a taller or square source and
   the subject's face/head is the part that must never get cropped out. */
.card-headshot img,
.card-nft img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 15%;
  border-radius: 4px;
  display: block;
}
/* ---------- .card-nft's real content: a holo-foil collectible card ----------
   Mocked up and approved as a standalone Artifact first (a pointer-tracked
   foil shimmer + 3D tilt, gem-shaped trait markers, trading-card anatomy),
   then fit into the existing 300x460 .team-photo box here. Colors are
   pulled from the actual Citizen #996 artwork (teal glass, jacket magenta,
   laser red) rather than the site's own --gold/--navy palette, scoped as
   local custom properties on .nft-card only — same "this one graphic gets
   its own palette" precedent diy.html's inline SVG diagrams already use,
   not a change to the site's global tokens. Type reuses the site's own
   faces (var(--serif) for the name, var(--mono) for stats/labels) rather
   than a new display font, per explicit direction earlier this session
   not to add fonts casually. */
.card-nft {
  perspective: 900px;
}
.nft-card {
  --mx: 0.5;
  --my: 0.5;
  --nft-teal: #0e3332;
  --nft-teal-deep: #071e1d;
  --nft-magenta: #8a3a7c;
  --nft-pink: #f0c3e6;
  --nft-foil: #dcb96b;
  --nft-foil-bright: #f3d896;
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 6px;
  padding: 2px;
  background: linear-gradient(145deg, var(--nft-foil-bright), var(--nft-magenta) 32%, var(--nft-teal) 55%, var(--nft-foil) 78%, var(--nft-foil-bright));
  background-size: 260% 260%;
  background-position: calc(var(--mx) * 100%) calc(var(--my) * 100%);
  transform-style: preserve-3d;
  transform: rotateY(calc((var(--mx) - 0.5) * 14deg)) rotateX(calc((var(--my) - 0.5) * -14deg));
  transition: transform 0.15s ease-out, background-position 0.15s ease-out;
}
.nft-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  background: linear-gradient(180deg, var(--nft-teal) 0%, var(--nft-teal-deep) 100%);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.nft-sheen {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  mix-blend-mode: color-dodge;
  opacity: 0.5;
  background: repeating-linear-gradient(115deg,
    rgba(255,255,255,0) 0%, rgba(255,190,230,0.5) 6%, rgba(190,255,240,0.5) 12%,
    rgba(255,235,160,0.5) 18%, rgba(200,190,255,0.5) 24%, rgba(255,255,255,0) 30%);
  background-size: 300% 300%;
  background-position: calc(var(--mx) * 220% - 60%) calc(var(--my) * 220% - 60%);
  transition: background-position 0.15s ease-out;
}
.nft-glow {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  opacity: 0.85;
  background: radial-gradient(circle 140px at calc(var(--mx) * 100%) calc(var(--my) * 100%), rgba(255,255,255,0.2), transparent 70%);
  mix-blend-mode: overlay;
}
.nft-head {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.65rem 0.35rem;
}
.nft-set-stamp {
  font-family: var(--mono);
  font-size: 0.46rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nft-foil-bright);
}
.nft-set-stamp b { color: var(--ink); font-weight: 600; }
.nft-collector-no {
  font-family: var(--mono);
  font-size: 0.56rem;
  color: var(--ink-dim);
}
.nft-art {
  position: relative;
  z-index: 2;
  margin: 0 0.65rem;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid rgba(220,185,107,0.28);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35);
  height: 210px;
  background: var(--nft-teal-deep);
}
.nft-art-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 12%;
  display: block;
  border-radius: 0;
}
.nft-cool-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  z-index: 3;
  text-align: right;
  line-height: 1;
  text-shadow: 0 1px 6px rgba(0,0,0,0.6);
}
.nft-cool-badge .n {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 1.35rem;
  color: var(--ink);
}
.nft-cool-badge .l {
  font-family: var(--mono);
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nft-foil-bright);
  display: block;
  margin-top: -2px;
}
.nft-name-plate {
  position: relative;
  z-index: 2;
  padding: 0.55rem 0.65rem 0.3rem;
}
.nft-name-plate h3 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  margin: 0;
}
.nft-name-plate p {
  font-family: var(--mono);
  font-size: 0.56rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--nft-pink);
  margin: 0.2rem 0 0;
}
.nft-trait-list {
  position: relative;
  z-index: 2;
  margin: 0.35rem 0.65rem 0;
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(220,185,107,0.28);
}
.nft-trait-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "title val" "desc desc";
  align-items: center;
  row-gap: 1px;
  column-gap: 0.4rem;
  padding: 0.32rem 0;
  border-bottom: 1px solid rgba(220,185,107,0.14);
}
.nft-trait-row:last-child { border-bottom: none; }
.nft-trait-title-line {
  grid-area: title;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.nft-trait-icon {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 1.5px;
  background: linear-gradient(135deg, var(--nft-foil-bright), var(--nft-foil) 48%, #8a6a2e 100%);
  box-shadow:
    0 0 0 1px rgba(0,0,0,0.4),
    inset -1px -1px 1.5px rgba(0,0,0,0.45),
    inset 1px 1px 1px rgba(255,255,255,0.65);
  transform: rotate(45deg);
}
.nft-trait-title {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.66rem;
  color: var(--ink);
}
.nft-trait-desc {
  grid-area: desc;
  display: block;
  font-family: var(--sans);
  font-size: 0.56rem;
  color: var(--ink-faint);
  padding-left: calc(7px + 0.4rem);
}
.nft-trait-val {
  grid-area: val;
  align-self: center;
  font-family: var(--mono);
  font-size: 0.56rem;
  color: var(--nft-foil-bright);
  white-space: nowrap;
}
.nft-footer {
  position: relative;
  z-index: 2;
  margin-top: auto;
  padding: 0.35rem 0.65rem 0.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid rgba(220,185,107,0.28);
}
.nft-chain {
  font-family: var(--mono);
  font-size: 0.42rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.nft-rarity-pip { display: flex; gap: 3px; }
.nft-rarity-pip span {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--nft-foil-bright);
  box-shadow: 0 0 3px var(--nft-foil-bright);
}
@media (prefers-reduced-motion: reduce) {
  .nft-card { transition: none; }
  .nft-sheen, .nft-glow { transition: none; }
}
.team-photo-label {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0;
  z-index: 10;
  background: rgba(17,51,96,0.9);
  padding: 0.4rem 0.8rem;
  border-radius: 3px;
  white-space: nowrap;
}
/* hover effect for interactivity cue */
.team-photo:hover {
  opacity: 0.95;
}
.team-photo:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.team-copy { flex: 0 0 500px; min-width: 0; }
.team-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(3rem, 5vw, 3.8rem);
  line-height: 1.05;
  color: var(--ink);
  margin: 0 0 0.5rem;
  /* same halo shadow as .headline - this is a separate class (team.html's
     own name/title treatment), so it didn't inherit the fix made there. */
  text-shadow: 0 0 14px rgba(0,0,0,0.4), 0 2px 4px rgba(0,0,0,0.35);
}
.team-eyebrow {
  font-family: var(--mono);
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin: 0.7rem 0 0;
}
.team-bio {
  font-family: var(--sans);
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--ink-soft);
  /* matches .team-creds's rendered width exactly (565px, measured live —
     .team-creds's own 56ch doesn't convert to the same px value as a ch
     unit set at this element's font-size/family), so the bio's right edge
     lines up with the divider line above Education/Recognition instead of
     stopping short of it. */
  max-width: 565px;
  margin: 0.9rem 0 0;
  text-align: justify;
  text-justify: inter-word;
}
/* the quote as a unit (mark + text) centers under the Education/
   Recognition block specifically — not the wider .team-copy column — by
   giving it the same 565px width as .team-bio/.team-creds and centering
   the flex row *within* that matched-width box, rather than centering
   .team-quote-lg itself (which would center against the full column and
   drift right of where the creds block actually sits). The mark stays at
   the immediate left of the text, not centered above it. */
.team-quote-lg {
  position: relative;
  width: 565px;
  max-width: 100%;
  margin: 2rem 0 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.85rem;
}
.team-quote-mark {
  flex: 0 0 auto;
  width: 36px;
  height: 27px;
  fill: var(--gold);
  opacity: 0.5;
  display: block;
  margin: 0.3rem 0 0;
}
.team-quote-lg p {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
  /* without a cap, a flex child with no intrinsic width shrinks to fill
     the ENTIRE remaining row width before centering has anything left to
     work with — the mark+text pair would span the full 565px box edge to
     edge instead of sitting as a compact, centered unit within it. 480px
     is the narrowest width this exact sentence still wraps to exactly two
     lines at — any narrower and it drops to three. */
  max-width: 520px;
  text-align: justify;
  text-justify: auto;
}
/* education/bar admission: two-column "documents" grammar with
   Education on left, Bar Admission on right. Kept deliberately compact
   (smaller type, tighter leading) since it's supporting detail behind
   the pull-quote's thesis, not the slide's main point. */
.team-creds {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.6rem 2.8rem;
  max-width: 56ch;
  margin-top: 1.8rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
}
.team-cred-label {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.7rem;
}
.team-creds ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.team-creds li {
  font-family: var(--sans);
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--ink-dim);
  padding-left: 1rem;
  position: relative;
}
.team-creds li::before {
  content: "";
  position: absolute;
  left: 1px; top: 0.58em;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--gold);
}
/* education entries get a bit more room than a single-line credential —
   degree on its own line, institution beneath in a quieter weight, the
   way a CV lists schooling rather than running both into one clause. */
.team-creds-edu { gap: 0.8rem; }
.team-creds .cred-title {
  display: block;
  color: var(--ink);
}
.team-creds .cred-org {
  display: block;
  color: var(--ink-faint);
  font-size: 0.68rem;
  margin-top: 0.2rem;
}
/* bar admission: the credential most worth leading with, so it gets its
   own weight — gold title instead of the plain ink used everywhere else
   in these two columns — and a little extra breathing room below it so
   it doesn't read as just another line in the list. */
.cred-highlight { margin-bottom: 0.3rem; }
.cred-highlight .cred-title {
  color: var(--gold-soft);
  font-weight: 600;
}

/* ---------- problem / solution card slides ---------- */
.slide-cards .slide-inner { max-width: 1040px; }
/* was serif italic; the sans body face reads quieter and more modern for a
   plain descriptive sentence, and matches `.lede` (used in this exact
   kicker/headline/subtitle slot on insights.html and team.html) instead of
   the two diverging on font family for no real reason. Still used on
   lifecycle.html/diy.html/_fractional-gc.html even though problem.html
   (the page this block is otherwise about) and practices.html both
   dropped their subtitle entirely. */
.lede-italic {
  font-family: var(--sans);
  font-size: clamp(0.95rem, 1.5vw, 1.06rem);
  color: var(--ink-soft);
  max-width: 58ch;
  line-height: 1.6;
  margin: 0 0 2.25rem;
}
/* diy.html only: the default 58ch wrap left a large empty block to the
   right of the header (headline + subtitle), above the tab row, since
   this slide's content column is wider than most. Widening just the wrap
   width — no new content — uses more of that row; scoped override rather
   than raising the global default, since lifecycle.html's subtitle still
   wraps correctly at 58ch. */
.slide-fvl .lede-italic { max-width: 80ch; }
.card-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}
/* Solid block, same recipe as lifecycle.html's .mt-card (deep azure-family
   fill + thin gold hairline, 8px radius, no hover glow/lift). The kicker +
   serif-title pairing was collapsed into one bold headline (see .card-title
   below) so each card reads as a single scannable statement instead of
   three separate lines. */
.card {
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 2.4rem 2.2rem;
  min-height: 12.75rem;
}

/* ---------- legibility for loose body copy on the textured background ---------- */
/* No visible panel behind the text (tried a frosted backing, then a more
   transparent one - the user wants no visible "window" at all). Instead,
   reuses the same halo-shadow technique already established for .headline/
   .kicker: an even, unoffset glow directly on the letterforms holds
   contrast against the star field without ever adding a box around it.
   Smaller/tighter than .headline's 14px halo since this is body-sized
   text - a big diffuse blur at this font size would just look muddy.
   Text already inside a card (.card-body, .cf-tier-desc, .svc-panel-blurb,
   .pa-desc, .mt-stage-copy, etc.) is left out - it already sits on that
   card's own fill and doesn't need this.
   Practice-area pages, blog posts, and the plain legal pages (terms/
   privacy/refund/sitemap/404) are all excluded here - .legal-section (used
   by both the legal pages and the practice pages' "Who This Is For"/"What
   We Handle" sections) now sits on the central frosted-column panel
   instead (.pa-main / .legal-page:not(.pa-footer)), so it no longer needs
   this halo. */
.lede,
.lede-italic,
.subtitle,
.cf-thesis,
.team-bio,
.terms-line,
.appendix-row p {
  text-shadow: 0 0 8px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.35);
}
.card-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.25;
  color: var(--ink);
  margin: 0 0 0.7rem;
}
.card-body {
  font-size: 1.05rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0;
}
.slide-footnote {
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}
.slide-footnote > p {
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0;
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}
/* the mono label above it is a single short line — justifying it would do
   nothing but risk stretching it if it ever wrapped */
.slide-footnote > p.fit-label { text-align: left; }
.fit-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.85rem;
}

/* ---------- slide 13: client fit (stage + market map + ICP) ----------
   A single argument in four movements: where you are (stage), what the
   market actually offers at each price point (map), who this is built for
   (ICP row), then the disqualifier paired with the call to action. */
.slide-clientfit .slide-inner { max-width: 1120px; }
.slide-clientfit .headline { max-width: none; }

/* same kicker/headline/subtitle slot as `.lede-italic` elsewhere in the
   deck, just wider — kept off the serif italic for the same reason */
.cf-thesis {
  font-family: var(--sans);
  font-weight: 500;
  font-size: clamp(1.02rem, 1.6vw, 1.24rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 76ch;
  margin: 0 0 2.1rem;
}

.cf-section { margin-bottom: 2.1rem; }
.cf-label {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}

/* ---- stage spectrum: five equal segments, the three you actually work
   in lit gold - the ends stay dim rather than absent, so the shape reads
   as "still on the map, just not the target" rather than "excluded" ---- */
.cf-stage-band { display: flex; gap: 6px; margin-bottom: 0.7rem; }
/* frosted-glass segments, same recipe as the .cf-tier cards below - no
   pigment of their own, just a translucent lift off the azure canvas. The
   "on" state used to be a solid gold fill, but with gold now used as a
   hairline/text accent everywhere else post-rework, a big solid block read
   as out of step - it's a brighter frosted tile with a gold border/text
   instead, accent rather than fill. */
.cf-stage-seg {
  flex: 1 1 0;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  position: relative;
}
.cf-stage-seg.is-on {
  background: rgba(11,29,58,0.34);
  border-color: var(--gold);
  color: var(--gold-soft);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-shadow: 0 1px 2px rgba(8,16,32,0.4);
}
.cf-stage-seg[data-note] {
  cursor: help;
  transition: background 0.2s ease, color 0.2s ease;
}
.cf-stage-seg[data-note]:hover {
  background: rgba(255,255,255,0.2);
}
/* An absolutely-positioned box shrink-to-fits against its containing block —
   here the 130px-wide segment — so max-width alone can never widen it past
   that. The measure has to be set explicitly, and once it is, a 50%-centred
   box would hang off the viewport on exactly the two segments that carry
   notes. So each anchors to its own side of the band instead. */
.cf-stage-seg[data-note]:hover::after {
  content: attr(data-note);
  position: absolute;
  top: calc(100% + 9px);
  width: min(430px, 78vw);
  background: var(--navy-deep);
  color: var(--ink-dim);
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  padding: 0.9rem 1.05rem;
  border-radius: 3px;
  border: 1px solid rgba(242,201,76,0.3);
  box-shadow: 0 10px 28px rgba(6,20,32,0.55);
  line-height: 1.6;
  white-space: normal;
  text-align: justify;
  text-wrap: pretty;
  hyphens: auto;
  z-index: 10;
  pointer-events: none;
}
.cf-stage-seg[data-note]:first-child:hover::after { left: 0; }
.cf-stage-seg[data-note]:last-child:hover::after { right: 0; }
.cf-stage-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.cf-stage-foot .is-em { color: var(--gold-soft); }
.cf-stage-foot .arr { width: 0.85em; height: 0.85em; }

/* ---- market map: same shared-baseline subgrid technique as the retainer
   tiers on fractional-gc, so the verdict line lands at the same height in
   all three cards regardless of how many lines the copy wraps to ---- */
.cf-map {
  display: grid;
  grid-template-columns: 1fr 1.08fr 1fr;
  grid-template-rows: auto auto 1fr auto;
  column-gap: 0.9rem;
  row-gap: 0;
  align-items: stretch;
  margin-bottom: 0.85rem;
}
/* solid block, same recipe as lifecycle.html's .mt-card: no border, no
   box-shadow, no hover lift/glow. "You are here" is marked by the solid
   gold flag badge and the kicker's gold-soft color alone, not by tinting
   the whole card gold, so there's still exactly one obviously-gold thing
   per card rather than a wash competing with the flag for attention. */
.cf-tier {
  position: relative;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4;
  border-radius: 8px;
  padding: 1.2rem 1.15rem 1.1rem;
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
}
/* base fill now matches the other two tiers - "You are here" is marked by
   the brighter gold border below, not a separate background color. */
.cf-tier.is-here { border-color: rgba(242,201,76,0.65); }
.cf-tier-flag {
  position: absolute;
  top: -9px;
  left: 1.15rem;
  background: var(--gold);
  color: var(--navy-deep);
  font-family: var(--mono);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border-radius: 2px;
}
.cf-tier-kicker {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.5rem;
}
.cf-tier.is-here .cf-tier-kicker { color: var(--gold-soft); }
.cf-tier-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.25;
  color: var(--ink);
  margin: 0 0 0.7rem;
}
.cf-tier-desc {
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0 0 auto;
  padding-bottom: 0.9rem;
  text-align: justify;
  text-justify: inter-word;
}
.cf-tier-verdict {
  font-family: var(--sans);
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
  border-top: 1px solid var(--line);
  padding-top: 0.75rem;
  margin: 0;
}
.cf-tier.is-here .cf-tier-verdict { color: var(--gold-soft); border-top-color: rgba(242,201,76,0.3); }

/* the graphic element that breaks up the slide's monotony: services on the
   left, the paper that backs them on the right, each list marked with a
   different accent so the two columns stay visually distinct at a glance */
.practice-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
}
/* a hairline divider plus generous padding between the two columns —
   reads like a structured document/cap-table split rather than two
   loosely related lists sitting side by side. */
.practice-col-docs {
  border-left: 1px solid var(--line);
  padding-left: 1.75rem;
}
.practice-col-label {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}
.practice-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}
.practice-col li {
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--ink-dim);
  padding-left: 1rem;
  position: relative;
}
.practice-col li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.58em;
  width: 6px; height: 1.5px;
  background: var(--gold);
}
.practice-col-docs li::before { background: var(--azure-bright); }

/* ---------- .svc-tabs/.svc-panel: equal-width tab row + card ----------
   Currently used by diy.html only (five tabs, one .svc-panel visible at a
   time via the shared wireTablist() helper in deck.js). The selected/
   unselected signal is borrowed from `.insight-filter` on the Insights
   slide (below): a colored underline bar that only the active item shows —
   a tab pattern this site already uses once, so leaning on the same
   grammar here means a visitor who's seen either slide already knows how
   both work. The underline is `currentColor` rather than a fixed accent,
   so it can pick up whatever accent color the active tab itself carries. */
.svc-tabs {
  display: flex;
  gap: 6px;
  margin: 0 0 1.6rem;
  padding-bottom: 10px;
  /* text and list content stop shy of the slide's own edge everywhere else
     on the page, but they don't have a hard colored border — a stray few
     px under the fixed nav arrow's corner is invisible. A five-way flex
     row of bordered pills makes the same pre-existing gutter geometry
     obvious, so unlike the rest of the slide this row keeps its own
     margin clear of the arrows across the ~769-1024px range where the
     row is still one line but the slide hasn't reached its max-width yet;
     the clamp tapers to 0 above that, where there's already room to spare. */
  padding-left: clamp(0px, calc(50px - 3.5vw), 24px);
  padding-right: clamp(0px, calc(50px - 3.5vw), 24px);
}
.svc-tab {
  flex: 1 1 0;
  justify-content: center;
  position: relative;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
/* a small lift toward the pointer, the same hover language the retainer
   tier cards on fractional-gc.html already use, so the row reads as
   pressable before a visitor ever reaches the color/underline cue */
.svc-tab:hover { transform: translateY(-2px); }
.svc-tab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 2px;
  background: currentColor;
  opacity: 0;
  transform: scaleX(0.6);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.svc-tab.is-active::after { opacity: 1; transform: scaleX(1); }

/* All five panels stack in the same grid cell instead of being swapped via
   `hidden` — a CSS Grid cell sizes to the tallest item placed in it even
   when the others are invisible, and grid items stretch to fill that cell
   by default. So the card's height is always the tallest panel among the
   five, whichever one happens to be showing, and the page stops jumping
   when a shorter tab follows a longer one. `visibility` (not `opacity` or
   `hidden`) is what hides the rest: it drops them from hit-testing and the
   accessibility tree exactly like `hidden` did, but — unlike `hidden`'s
   `display:none` — still lets them contribute to the grid's height. */
.svc-panels {
  display: grid;
  /* keeps each panel's outer edge flush with the tab pills above it,
     which carry this same clamp as clearance from the fixed nav arrows —
     without it the panel card is wider than the pill row it sits under. */
  padding-left: clamp(0px, calc(50px - 3.5vw), 24px);
  padding-right: clamp(0px, calc(50px - 3.5vw), 24px);
}
.svc-panel { grid-area: 1 / 1; visibility: hidden; }
.svc-panel.is-active { visibility: visible; }

/* without a frame, the blurb + columns just sat in open space under the
   tab row with nothing marking where the selected tab's content begins or
   ends — the same neutral card language as `.tier`/`.card` elsewhere in
   the deck gives it a floor to sit on. Left uncolored on purpose: the tab
   above already carries the stage's accent, and tinting the card to match
   would mean five different panel colors competing with five already-
   colorful tabs rather than one clear focal color per screen. */
.svc-panel {
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 1.6rem 1.75rem;
}
/* matches `.lede-italic` — same sans body face, no italic — so the panel's
   lead sentence reads as the same voice as the slide's own subtitle above
   the tabs, not a separate, more decorative register */
.svc-panel-blurb {
  font-family: var(--sans);
  font-size: clamp(0.92rem, 1.4vw, 1.02rem);
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 68ch;
  margin: 0 0 1.5rem;
}
/* the card's own border is the section's divider now, so the columns
   don't need a second rule directly above them */
.svc-panel .practice-columns { border-top: none; padding-top: 0; }

/* ---------- diy.html only: quiet editorial tabs ----------
   Same visual language as the outer practice-area tabs on practices.html
   (.practice-tabs/.practice-tab below, slide 05) — replaces the earlier
   gold sliding-pill treatment (a "switch" affordance that read out of step
   with the rest of the deck's flat/hairline language). Not literally
   reusing .practice-tab's class name: .svc-tabs/.svc-tab still drive
   diy.html's own five-panel wiring in deck.js's activateSvcTab (renaming
   would break that), so this just restyles the existing selectors to
   match instead. Scoped to .slide-fvl (diy.html's own scoping class, same
   pattern as `.slide-fvl .svc-panel` above) so the base .svc-tabs recipe
   (used nowhere else currently) is untouched. Unlike .practice-tabs
   (natural-width, left-clustered), these tabs stretch to fill the full
   row via flex:1 so the row's edges line up with the .svc-panel graphic's
   edges below it — a deliberate deviation from the slide-05 recipe for
   that alignment. flex-direction/flex-wrap set explicitly so this wins
   over the sitewide mobile column-stack rule at every width; the 140px
   flex-basis floor is what triggers wrapping once 5 equal columns would
   get too narrow to read, same graceful-wrap idea .practice-tabs uses. */
.slide-fvl .svc-tabs {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 1.5rem;
  padding-bottom: 0.85rem;
  border-radius: 0;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  box-shadow: none;
}
.slide-fvl .svc-tab {
  flex: 1 1 140px;
  justify-content: center;
  padding: 0 0 0.9rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: none;
  border: none;
  border-radius: 0;
}
.slide-fvl .svc-tab:hover { transform: none; color: var(--gold-bright); }
.slide-fvl .svc-tab:hover::after { opacity: 0.5; transform: scaleX(1); }
.slide-fvl .svc-tab::after {
  background: var(--gold);
  bottom: -1px;
  transform: scaleX(0.5);
}
.slide-fvl .svc-tab.is-active { color: var(--gold-bright); }
.slide-fvl .svc-tab:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

/* ---------- practice-areas.html: outer "which area" tabs ----------
   One level up from .svc-tabs/.svc-panels (which pick the stage within an
   area). Deliberately monochrome/gold rather than reusing the five
   stage-tab colors — six more distinct hues on top of the five already in
   use would compete for attention rather than reading as a clear hierarchy
   of "pick an area, then pick a stage". */
/* redesigned as a quiet editorial nav rather than a filled pill row —
   natural-width text tabs with generous spacing and a hairline baseline,
   so this first-level "pick the area" choice reads as calmer and more
   considered than the colorful stage-pill row underneath it. The sliding
   gold underline reuses the same indicator technique as .svc-tab::after
   below, just sized to the text instead of a full pill. */
.practice-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 1.9rem;
  margin: 0 0 1.75rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
}
.practice-tab {
  position: relative;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: none;
  border: none;
  border-radius: 0;
  padding: 0 0 0.9rem;
  transition: color 0.2s ease;
}
.practice-tab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--gold);
  opacity: 0;
  transform: scaleX(0.5);
  transform-origin: left;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.practice-tab:hover { color: var(--gold-bright); }
.practice-tab:hover::after { opacity: 0.5; transform: scaleX(1); }
.practice-tab.is-active, .practice-tab:focus-visible {
  color: var(--gold-bright);
}
.practice-tab.is-active::after,
.practice-tab:focus-visible::after {
  opacity: 1;
  transform: scaleX(1);
}

/* NOT the same visibility-toggle trick .svc-panels uses below — that trick
   relies on `visibility: hidden` cascading down, but CSS lets a descendant
   set its own `visibility: visible` right back (which .svc-panel.is-active
   does, inside every group). Nesting two independent visibility toggles
   meant every inactive group's own "is-active" stage panel re-declared
   itself visible and bled through regardless of its group being "hidden".
   `display: none` has no such loophole — an inactive group's descendants
   can't override it back on. Trade-off: switching areas can now change the
   card's height (each area's tallest stage differs slightly), where the
   nested stage tabs below don't. */
.practice-group { display: none; }
.practice-group.is-active { display: block; }

/* slide 5 only: no subtitle under the headline here (unlike most other
   slides), so the headline sits directly above a full tab row with only
   its own global 1.25rem margin for clearance — a bit tight against
   something as visually heavy as a bordered nav row. Scoped bump for
   breathing room; doesn't touch the global .headline default other
   slides rely on. */
.slide-practice-areas .headline { margin-bottom: 1.6rem; }

/* slide 5 only: each practice area is now a single static card (no more
   nested Formation-Exit stage tabs — removed along with .svc-tabs/
   .svc-panels here entirely). A dedicated class rather than reusing
   .svc-panel: that class defaults to `visibility: hidden` and only shows
   via `.is-active`, a toggle designed for the multi-panel stack diy.html
   still uses — a single always-visible card has nothing to toggle it back
   on, so reusing it would just render the card invisible. Same solid-block
   card look as the rest of the deck either way, just a slightly larger
   radius/padding to suit this slide's single wide panel. */
.slide-practice-areas .pa-card {
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 1.85rem 2rem;
}
/* the card's own border is the section's divider now, so the columns
   inside don't need the base .practice-columns top border/padding too.
   Gap left at the base 2rem now that the card holds only the description
   + two columns — these classes are practices.html-exclusive (confirmed
   sitewide), so editing the base rule directly rather than adding a third
   layer of override is simpler and has no other page to conflict with. */
.slide-practice-areas .pa-card .practice-columns { border-top: none; padding-top: 0; }
/* names the area inside the card itself — previously only the tab label
   above named it, so a screenshot or a scrolled view of just the card
   carried no label of its own. Same serif heading recipe as .mt-stage-name
   on the lifecycle slide, not a new pattern. */
.slide-practice-areas .pa-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--ink);
  margin: 0 0 0.6rem;
}
/* same voice as .lede-italic/.svc-panel-blurb — a short lead sentence
   ahead of the two columns, giving each area a line of its own instead of
   dropping straight into two bare lists. Margin rounded to the same
   1.5rem step the rest of this slide's rhythm now uses (headline 1.6rem,
   tabs 1.75rem) rather than the odd 1.6rem it had picked up mid-revision. */
.slide-practice-areas .pa-desc {
  font-family: var(--sans);
  font-size: 0.94rem;
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 62ch;
  margin: 0 0 1.5rem;
}
/* links out to the dedicated /practices/<slug> page for this area (see
   Changes doc: SEO — each area now also has its own indexable page).
   Same link recipe as .insight-read (gold, arrow nudges right on hover)
   for a consistent "read more" affordance sitewide, not a new pattern. */
.slide-practice-areas .pa-view-more {
  margin-top: 1.4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--gold-soft);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 0.2s ease;
}
.slide-practice-areas .pa-view-more:hover,
.slide-practice-areas .pa-view-more:focus-visible { color: var(--gold); }
.slide-practice-areas .pa-view-more .arr { transition: transform 0.2s ease; }
.slide-practice-areas .pa-view-more:hover .arr { transform: translateX(3px); }

/* ---------- problem-solution.html: Problem / Solution switch ----------
   Same two-tab idea as .practice-tabs. The headline above the tabs is now
   the only static copy — no subtitle — so only the card grid below
   switches. Same display:none/block toggle as .practice-group for
   .ps-group, for the same reason: a visibility-based toggle would have
   the identical descendant-override problem covered above.

   Styled as a segmented-control pill (fixed-width track + a sliding gold
   thumb behind the active label) rather than two separate bordered
   buttons, for a more premium/pitch-deck feel. The thumb is a real
   element (.ps-tab-thumb, first child of .ps-tabs) positioned with
   `transform: translateX()` driven by `data-active` on .ps-tabs itself
   (set in deck.js's activatePsTab) rather than by JS measuring layout —
   with exactly two fixed-width tabs, a CSS attribute selector is simpler
   and can't drift out of sync with a resize. */
.ps-tabs {
  position: relative;
  display: flex;
  margin: 0 0 1.75rem;
  width: 320px;
  max-width: 100%;
  padding: 5px;
  border-radius: 999px;
  background: rgba(6,14,26,0.55);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.35);
  /* centered deliberately, unlike the rest of the deck's kicker-anchored
     content. */
  margin-left: auto;
  margin-right: auto;
}
.ps-tab-thumb {
  position: absolute;
  top: 5px;
  left: 5px;
  width: calc(50% - 5px);
  height: calc(100% - 10px);
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold));
  box-shadow: 0 2px 10px rgba(242,201,76,0.45);
  transition: transform 0.32s cubic-bezier(0.65, 0, 0.35, 1);
}
.ps-tabs[data-active="solution"] .ps-tab-thumb { transform: translateX(100%); }
.ps-tab {
  position: relative;
  z-index: 1;
  flex: 1 0 50%;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 0.6rem 1.4rem;
  transition: color 0.2s ease;
}
.ps-tab:hover { color: var(--gold-bright); }
.ps-tab.is-active {
  color: var(--navy);
  font-weight: 600;
}
.ps-tab.is-active:hover { color: var(--navy); }
.ps-tab:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}
.ps-group { display: none; }
.ps-group.is-active { display: block; }

/* ---------- fractional GC: retainer tiers ---------- */
/* three columns need more room than the standard 900px reading measure */
.slide-tiers .slide-inner { max-width: 1060px; }

/* six shared row lines — name, price, hours, who-it's-for, the list, fine print.
   Each card is a subgrid of these, so the two divider rules land at exactly the
   same height in all three columns however many lines the copy wraps to. */
.tier-grid {
  display: grid;
  /* the middle tier is the one most clients land on, so it gets the extra width */
  grid-template-columns: 1fr 1.08fr 1fr;
  grid-template-rows: auto auto auto auto 1fr auto;
  column-gap: 0.9rem;
  row-gap: 0;
  align-items: stretch;
  margin-bottom: 1.35rem;
}
.tier {
  position: relative;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 6;
  border-radius: 4px;
  padding: 1.3rem 1.15rem;
  background: rgba(244,241,232,0.03);
  border: 1px solid var(--line);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
/* both cards' borders must be the same weight or the shared row lines sit half
   a pixel apart — the middle tier gets its emphasis from an inset ring instead */
.tier-embedded { box-shadow: inset 0 0 0 1px rgba(242,201,76,0.45); }
.tier:hover { transform: translateY(-2px); }

.tier-oncall { background: rgba(46,139,154,0.1); border-color: rgba(46,139,154,0.42); }
.tier-oncall:hover { border-color: var(--gold); box-shadow: 0 0 16px rgba(242,201,76,0.25); }
.tier-oncall .tier-name, .tier-oncall .tier-hours { color: #7FC4D4; }

.tier-embedded { background: rgba(242,201,76,0.09); border-color: rgba(242,201,76,0.6); }
.tier-embedded:hover {
  border-color: var(--gold);
  box-shadow: inset 0 0 0 1px rgba(242,201,76,0.45), 0 0 20px rgba(242,201,76,0.28);
}
.tier-embedded .tier-name, .tier-embedded .tier-hours { color: var(--gold-soft); }
.tier-embedded .tier-for, .tier-embedded .tier-fine { border-color: rgba(242,201,76,0.25); }

.tier-dedicated { background: rgba(36,104,206,0.1); border-color: rgba(36,104,206,0.45); }
.tier-dedicated:hover { border-color: #2468CE; box-shadow: 0 0 16px rgba(36,104,206,0.25); }
.tier-dedicated .tier-name, .tier-dedicated .tier-hours { color: #8FB4E0; }

/* the "most clients" flag sits astride the card's top border */
.tier-flag {
  position: absolute;
  top: -9px;
  left: 1.15rem;
  margin: 0;
  background: var(--gold);
  color: var(--navy-deep);
  font-family: var(--mono);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border-radius: 2px;
}
.tier-name {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0 0 0.55rem;
}
.tier-price {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.4rem, 2.2vw, 1.7rem);
  line-height: 1.1;
  color: var(--ink);
  margin: 0 0 0.15rem;
}
.tier-price span {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--ink-faint);
}
.tier-hours {
  font-family: var(--mono);
  font-size: 0.66rem;
  margin: 0 0 0.85rem;
}
.tier-for {
  font-size: 0.78rem;
  line-height: 1.5;
  color: rgba(244,241,232,0.58);
  margin: 0 0 0.85rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
}
/* margin-bottom:auto pins .tier-fine to the bottom so the fine print lines
   up across all three cards regardless of how many items each one lists */
.tier-list {
  list-style: none;
  margin: 0 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.42rem;
}
.tier-list li {
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-dim);
  padding-left: 0.95rem;
  position: relative;
}
.tier-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 1.5px;
  background: currentColor;
  opacity: 0.55;
}
.tier-inherit {
  padding-left: 0 !important;
  font-family: var(--mono);
  font-size: 0.6rem !important;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint) !important;
  margin-bottom: 0.15rem;
}
.tier-inherit::before { display: none; }
.tier-fine {
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--ink-faint);
  margin: 0.9rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}
.tier-fine em { font-style: normal; color: var(--gold-soft); }
.tier-dedicated .tier-fine em { color: #8FB4E0; }

/* ---------- slide 1: cover ---------- */
/* at desktop/tablet widths the cover shares the same fixed-canvas scaling as
   every other slide (see the theatre-mode block above) — no special sizing
   needed here anymore. It keeps its own override only on mobile (below),
   where the fixed-canvas treatment doesn't apply at all. */
/* the one deliberate exception to the deck-wide top-anchored kicker
   (.slide's align-items: flex-start, above): the cover is a title card,
   not a content slide, and centering reads better for a wordmark + one
   line of subtitle than pinning it to the top of a mostly-empty card. */
.slide-cover { align-items: center; }
.slide-cover .slide-inner { text-align: left; }
.confidential-stamp {
  position: absolute;
  top: clamp(1.5rem, 4vw, 3rem);
  right: clamp(1.5rem, 4vw, 3rem);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--ink-faint);
  border: 1px solid var(--line);
  padding: 0.35rem 0.7rem;
  transform: rotate(4deg);
  user-select: none;
  pointer-events: auto;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.confidential-stamp:hover {
  color: var(--gold-soft);
  border-color: var(--gold);
}
.ad-stamp {
  position: absolute;
  top: clamp(1.5rem, 4vw, 3rem);
  left: clamp(1.5rem, 4vw, 3rem);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  color: var(--ink-faint);
  border: 1px solid var(--line);
  padding: 0.35rem 0.7rem;
  transform: rotate(-4deg);
  user-select: none;
  pointer-events: auto;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.ad-stamp:hover {
  color: var(--gold-soft);
  border-color: var(--gold);
}
.wordmark {
  font-family: var(--serif);
  /* 600, not 700: the cover wordmark was the only element on the site using
     Playfair Bold, and that one weight was the single largest font file in
     the deploy and the largest embed in the PDF export */
  font-weight: 600;
  font-size: clamp(3rem, 9vw, 6.5rem);
  line-height: 1.2;
  margin: 0 0 1rem;
  letter-spacing: -0.01em;
}
/* "Azure" — gold highlight, lettering knocked out to the slide background */
.wm-azure {
  /* same --gold-on-azure token as the kicker - lettering is the brand's
     own bright azure instead of navy, spelling out "Azure" in the actual
     azure color. */
  background: var(--gold-on-azure);
  color: var(--azure-bright);
  -webkit-text-fill-color: var(--azure-bright);
  padding: 0.02em 0.14em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* "Legal" — plain white */
.wm-legal {
  /* same --gold-on-azure token as the kicker and the "Azure" box - gold
     text sitting directly on the bright canvas, not white. */
  color: var(--gold-on-azure);
  -webkit-text-fill-color: var(--gold-on-azure);
}
.subtitle {
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  color: #FFFFFF;
  font-style: italic;
  font-family: var(--serif);
  max-width: 32ch;
  margin: 0;
}
/* The cover alternates two taglines - the default line and the ECVC
   practice-area line - so the phrase itself is part of what gets surfaced
   on the page, not just buried in meta/schema. Both phrases share one grid
   cell (a stacking trick that auto-sizes the container to the taller of
   the two) and cross paths: the outgoing phrase exits right, the incoming
   one enters from the left, driven by the small script at the bottom of
   index.html. */
.subtitle-rotator {
  display: grid;
  max-width: 42ch;
}
.subtitle-phrase {
  grid-area: 1 / 1;
  transform: translateX(-60px);
  opacity: 0;
  transition: transform 0.7s ease, opacity 0.7s ease;
}
.subtitle-phrase.is-active { transform: translateX(0); opacity: 1; }
.subtitle-phrase.is-exiting { transform: translateX(60px); opacity: 0; }
.subtitle-phrase.is-resetting { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .subtitle-phrase { transition: none; }
}

/* ---------- lifecycle & founder-vs-lawyer diagram slides ---------- */
.slide-diagram .slide-inner { max-width: 1100px; }
.slide-diagram .headline { max-width: none; }

/* ---------- slide 4 (lifecycle.html): vertical-tab accordion ----------
   Redesigned from 6 simultaneously-visible flat cards (4-up grid + 2-up
   "ongoing" grid) into a single row of 5 vertical strips sitting side by
   side: Formation, Scaling (merged Fundraising + Scaling), Exit,
   Governance, Fractional GC. Clicking one widens it to reveal its full
   content while the rest narrow to labeled strips - one open at a time,
   Formation by default. See wireAccordion() in deck.js. Frosted-glass
   recipe (--deck-card-fill/--deck-card-border/blur) carries over
   unchanged from the old cards. */
.slide-lifecycle .lede-italic {
  margin-bottom: 1.4rem;
}
.slide-lifecycle .mt-rail {
  display: flex;
  flex-direction: column;
}
.slide-lifecycle .mt-vaccordion {
  display: flex;
  gap: 0;
  height: 420px;
}
.slide-lifecycle .mt-vaccordion-item {
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 0 0 108px;
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  overflow: hidden;
  transition: flex-grow 0.45s ease, flex-basis 0.45s ease, background 0.2s ease, border-color 0.2s ease;
  /* Left edge: concave notch cut INTO the card from the true left edge
     (0,0)/(0,100%) corners, point pulled inward to 18px - a shallow bite
     taken out, reading as pointing rightward/forward. Right edge: mirror-
     opposite (convex) - the flat top-right/bottom-right corners recede
     INWARD to (100% - 18px), while the point itself reaches the true
     right edge (100%) at vertical center. Receding the flat parts inward
     (rather than placing the point past 100%) is what makes the convex
     tip actually visible - clip-path can only subtract from what's
     already painted inside the box, it can't add new paintable area
     beyond it. Together the two edges interlock into one continuous
     forward-flowing chevron chain down the row - but only across the
     3-stage sequence (see the per-item overrides below); Governance/
     Fractional GC are ongoing support, not steps, so they stay flat. */
  clip-path: polygon(
    0 0, calc(100% - 18px) 0, 100% 50%, calc(100% - 18px) 100%, 0 100%, 18px 50%
  );
}
/* Formation is the first stage - nothing precedes it, so its left edge
   stays flat rather than carrying an incoming-arrow notch. */
.slide-lifecycle .mt-vaccordion-item:first-child {
  clip-path: polygon(
    0 0, calc(100% - 18px) 0, 100% 50%, calc(100% - 18px) 100%, 0 100%
  );
}
/* Exit is the last of the 3-stage sequence - the arrow chain ends here,
   so its right edge is flat (no outgoing arrow into Governance, which
   isn't "next" in the journey, just ongoing support alongside it). */
.slide-lifecycle .mt-vaccordion-item:nth-child(3) {
  clip-path: polygon(
    0 0, 100% 0, 100% 100%, 0 100%, 18px 50%
  );
}
/* Governance and Fractional GC are ongoing support, not steps in the
   sequence - flat on both edges, no arrow motif at all. */
.slide-lifecycle .mt-vaccordion-item:nth-child(4),
.slide-lifecycle .mt-vaccordion-item:nth-child(5) {
  clip-path: none;
}
.slide-lifecycle .mt-vaccordion-item:hover:not(.is-open) {
  background: rgba(255,255,255,0.19);
}
/* Gold border marks the open tab as *selected*, not just *wide* - same
   signal the deck already uses elsewhere for an active tab/tier
   (.practice-tab.is-active, .cf-tier.is-here). */
.slide-lifecycle .mt-vaccordion-item.is-open {
  flex: 1 1 0;
  border-color: var(--gold-bright);
}
/* Formation/Scaling/Exit are a sequence; Governance/Fractional GC are
   always-on support, not a stage you move through - a wider gap +
   hairline keep the two groups visually distinct now that the text
   labels ("01"/"Ongoing") that used to signal this are gone. */
.slide-lifecycle .mt-vaccordion-item:nth-child(4) {
  margin-left: 19px;
}
/* base row gap is 0 (the arrow tips themselves carry the visual spacing
   for the sequence cards) - Fractional GC keeps the original 4px gap
   from Governance since neither has an arrow tip to rely on. */
.slide-lifecycle .mt-vaccordion-item:nth-child(5) {
  margin-left: 4px;
}
/* Scaling/Exit overlap their own box into the previous card's box by
   12px so the arrow TIPS end up close together (the concave notch pulls
   a card's own point 18px in from its left edge, so with 0 box gap the
   tips would otherwise sit 18px apart - a wider visual gap than the
   flat-edge Governance/Fractional GC pair's plain 4px gap). Overlapping
   the boxes brings the tip-to-tip distance down to a comparable ~6px;
   the overlap itself lands only within each card's own clipped-away
   notch area (empty, not painted), so the two frosted fills don't
   visibly double up. */
.slide-lifecycle .mt-vaccordion-item:nth-child(2),
.slide-lifecycle .mt-vaccordion-item:nth-child(3) {
  margin-left: -12px;
}
.slide-lifecycle .mt-vaccordion-item:nth-child(4)::before {
  content: "";
  position: absolute;
  left: -14px;
  top: 12%;
  bottom: 12%;
  width: 1px;
  background: var(--line);
}

.slide-lifecycle .mt-vaccordion-heading {
  margin: 0;
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  transition: flex-grow 0.45s ease;
}
.slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-heading {
  flex: 0 0 auto;
}
.slide-lifecycle .mt-vaccordion-trigger {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  padding: 18px 10px;
  font: inherit;
  color: inherit;
  text-align: left;
  transition: flex-grow 0.45s ease, padding 0.3s ease;
}
.slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-trigger {
  flex: 0 0 auto;
  padding: 18px 22px 10px;
}
.slide-lifecycle .mt-vaccordion-trigger:focus-visible {
  outline: 2px solid var(--gold-soft);
  outline-offset: -2px;
}

/* Collapsed face: a single rotated label, using transform (not
   writing-mode - writing-mode can't be transitioned, so a crossfade-only
   approach could never actually rotate). Positioned absolutely so it can
   rotate/fade independently of the expanded header, which occupies
   normal flow once open. */
.slide-lifecycle .mt-vaccordion-face-collapsed {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.slide-lifecycle .mt-vaccordion-vlabel {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
  transform: rotate(90deg);
  opacity: 1;
  transition: transform 0.45s ease, opacity 0.3s ease;
}
.slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-vlabel {
  transform: rotate(0deg);
  opacity: 0;
}
/* Title treatment reuses the deck's own kicker+headline pairing (every
   other slide pairs a small mono kicker with a large serif headline;
   this component had invented an unrelated third treatment before) -
   same font/size/case in both the rotated and flat states, so the
   rotation reads as one title turning, not two different labels
   swapping. */
.slide-lifecycle .mt-vaccordion-vlabel .mt-stage-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.5rem;
  color: var(--ink);
  margin: 0;
  text-shadow: 0 0 10px rgba(0,0,0,0.35), 0 2px 3px rgba(0,0,0,0.3);
}

/* Expanded face: kicker (mono, gold, small - states this stage's
   position in the arc) stacked above the same serif title, instead of
   a bare label sitting alone. */
.slide-lifecycle .mt-vaccordion-face-expanded {
  display: none;
  flex-direction: column;
  gap: 0.3rem;
  width: 100%;
}
.slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-face-expanded {
  display: flex;
}
/* Same treatment as the slide's own .kicker (font, tracking, color, and
   the dark stroke + soft shadow that keeps gold letterforms from
   vibrating against the bright azure background) - this is a kicker in
   the same sense, just scoped to one tab instead of the whole slide. */
.slide-lifecycle .mt-vaccordion-kicker {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-on-azure);
  -webkit-text-stroke: 0.25px rgba(8, 20, 45, 0.3);
  text-shadow: 0 1px 2px rgba(4, 12, 28, 0.3);
  margin: 0;
}
.slide-lifecycle .mt-vaccordion-face-expanded .mt-stage-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.5rem;
  color: var(--ink);
  margin: 0;
  text-shadow: 0 0 10px rgba(0,0,0,0.35), 0 2px 3px rgba(0,0,0,0.3);
}

.slide-lifecycle .mt-vaccordion-panel {
  flex: 0 0 0;
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: flex-grow 0.45s ease, opacity 0.25s ease;
}
.slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-panel {
  flex: 1 1 auto;
  opacity: 1;
  transition: flex-grow 0.45s ease, opacity 0.3s ease 0.2s;
}
.slide-lifecycle .mt-vaccordion-panel-inner {
  height: 100%;
  padding: 6px 22px 20px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.75rem;
  min-height: 0;
}
.slide-lifecycle .mt-stage-copy {
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0;
}
.slide-lifecycle .mt-card-docs-label {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin: 0 0 0.6rem;
}
.slide-lifecycle .mt-card-docs {
  list-style: none;
  margin: 0;
  padding: 0.7rem 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.slide-lifecycle .mt-card-docs li {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  line-height: 1.5;
  color: var(--ink-dim);
  padding-left: 1rem;
  position: relative;
}
.slide-lifecycle .mt-card-docs li::before {
  content: "\2013";
  position: absolute;
  left: 0;
  color: var(--ink-faint);
}
/* Key Services sits beside Key Documents rather than stacked above it —
   same two-lists-side-by-side grammar as .practice-columns on practices.html
   (see the comment near .site-nav-col + .site-nav-col), but keeping this
   card's own mono/gold .mt-card-docs typography for both lists instead of
   switching to .practice-col's serif style, so the two columns read as one
   card rather than two different design languages stitched together. */
.slide-lifecycle .mt-card-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.75rem;
}
.slide-lifecycle .mt-card-col-docs {
  border-left: 1px solid var(--line);
  padding-left: 1.75rem;
}

@media (prefers-reduced-motion: reduce) {
  .slide-lifecycle .mt-vaccordion-item,
  .slide-lifecycle .mt-vaccordion-trigger,
  .slide-lifecycle .mt-vaccordion-panel,
  .slide-lifecycle .mt-vaccordion-vlabel {
    transition: none;
  }
}
/* Below 769px the deck's fixed-canvas theatre-mode scaling drops out and
   the page reflows instead (same threshold every other per-slide mobile
   override in this file uses) - the side-by-side arrow-chevron row has
   no room to breathe at that width, so it collapses to a plain top-to-
   bottom stack: full-width bars, no rotation, no arrow notches. Same
   wireAccordion() JS drives both layouts unchanged - only the CSS shape
   differs. */
@media (max-width: 768px) {
  .slide-lifecycle .mt-vaccordion {
    flex-direction: column;
    height: auto;
    gap: 8px;
  }
  .slide-lifecycle .mt-vaccordion-item,
  .slide-lifecycle .mt-vaccordion-item:first-child,
  .slide-lifecycle .mt-vaccordion-item:nth-child(2),
  .slide-lifecycle .mt-vaccordion-item:nth-child(3),
  .slide-lifecycle .mt-vaccordion-item:nth-child(4),
  .slide-lifecycle .mt-vaccordion-item:nth-child(5) {
    flex: 0 0 auto;
    width: 100%;
    margin-left: 0;
    clip-path: none;
  }
  .slide-lifecycle .mt-vaccordion-item:nth-child(4) {
    margin-top: 14px;
  }
  .slide-lifecycle .mt-vaccordion-item:nth-child(4)::before {
    left: 12%;
    right: 12%;
    top: -8px;
    bottom: auto;
    width: auto;
    height: 1px;
  }
  /* the rotated label only makes sense in the narrow vertical strip -
     in a full-width bar it just sits inline, unrotated, next to the
     kicker/title that appears once the bar opens. */
  .slide-lifecycle .mt-vaccordion-face-collapsed {
    position: static;
    inset: auto;
  }
  .slide-lifecycle .mt-vaccordion-vlabel {
    transform: none;
  }
  .slide-lifecycle .mt-vaccordion-trigger {
    padding: 16px;
  }
  .slide-lifecycle .mt-vaccordion-item.is-open .mt-vaccordion-trigger {
    padding: 16px 16px 8px;
  }
  /* stacked single column: the border-left divider between Key Services
     and Key Documents no longer separates anything side by side, so drop
     it rather than leave a stray vertical rule down the middle of a
     full-width card (each column already gets its own border-top from
     .mt-card-docs). */
  .slide-lifecycle .mt-card-cols {
    grid-template-columns: 1fr;
    gap: 1.4rem;
  }
  .slide-lifecycle .mt-card-col-docs {
    border-left: none;
    padding-left: 0;
  }
}
/* ---------- slide 7: insights ---------- */
.slide-insights .slide-inner { max-width: 1040px; }
/* No .lede on this slide (removed: redundant with the headline, and the
   fixed-height canvas needs the vertical room more than the subtitle
   earns its keep) - close the headline's own trailing margin down so the
   filters/grid sit right under it instead of leaving the gap a .lede
   would normally have filled. */
.slide-insights .headline { margin-bottom: 0.5rem; }

.insight-filters {
  display: flex;
  gap: 1.5rem;
  margin: 1.75rem 0 1.5rem;
  border-bottom: 1px solid var(--line);
}
.slide-insights .insight-filters { margin-top: 0.5rem; }
.insight-filter {
  background: none;
  border: none;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  padding: 0 0 0.75rem;
  position: relative;
  transition: color 0.2s ease;
}
.insight-filter::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--gold-bright);
  opacity: 0;
  transform: scaleX(0.6);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.insight-filter:hover { color: var(--gold-bright); }
.insight-filter.is-active { color: var(--gold-bright); }
.insight-filter.is-active::after { opacity: 1; transform: scaleX(1); }

.insight-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.1rem;
  margin-bottom: 1.75rem;
}
/* Insights slide only: fixed-size cards instead of the blog archive's
   stretch-to-fill columns — the slide always renders exactly 8 cards / 4
   columns (deck.js caps the fetch at limit=8 for this reason), so a static
   width reads more intentional than cards stretching to fill 1040px. */
.slide-insights .insight-grid {
  grid-template-columns: repeat(4, 1fr);
  margin-bottom: 2rem;
}
/* block-level, not the base rule's inline-flex — inline-flex is an
   inline-level box that sits inside a line box and inherits extra space
   from the surrounding line-height on top of its own margin, so it lands
   noticeably lower than a plain margin-top would suggest. width: fit-content
   keeps it sized to its own text instead of stretching full width like a
   normal block box would — otherwise the hover underline (border-bottom)
   spans the whole slide instead of just "View all articles". */
.slide-insights .explore-link { display: flex; width: fit-content; }
/* solid block, same recipe as lifecycle.html's .mt-card: no border, no
   box-shadow, no hover lift/glow. */
.insight-card {
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.insight-card.is-hidden { display: none; }
/* clamped to 2 lines with a matching min-height (not just the clamp alone)
   so every card in a row reserves the same title space whether its own
   title actually wraps to 1 line or 2 — otherwise the meta/teaser/foot
   below drift out of alignment across the row depending on title length. */
.insight-title {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  color: var(--ink);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.73rem;
}
.insight-title a { color: inherit; text-decoration: none; transition: color 0.2s ease; }
.insight-title a:hover, .insight-title a:focus-visible { color: var(--gold-bright); }
.insight-author {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin: 0;
}
.insight-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin: 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
/* single line, ellipsis-truncated: a post can carry several category tags,
   and without this the joined "A, B, C..." string wraps the meta row
   across multiple lines instead of sitting flush with the date. min-width:
   0 is required for a flex child to shrink/truncate below its content
   width at all. */
.insight-tag {
  /* grey, matching its sibling .insight-date on the same meta line -
     these are both metadata, not accent/action elements, so neither
     needs a brand color. */
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.insight-date { color: var(--ink-faint); flex: none; }
.insight-teaser {
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0;
  flex-grow: 1;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.insight-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 0.2rem;
}
.insight-time {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--ink-faint);
  letter-spacing: 0.04em;
  white-space: nowrap;
  flex: none;
}

.insight-read {
  align-self: flex-start;
  background: none;
  border: none;
  color: var(--gold-soft);
  font-size: 0.82rem;
  font-weight: 500;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: color 0.2s ease;
  text-decoration: none;
  cursor: pointer;
}
.insight-read:hover, .insight-read:focus-visible { color: var(--gold); }
.insight-read span { transition: transform 0.2s ease; }
.insight-read:hover span { transform: translateX(3px); }

/* ---------- slide 9: ask ---------- */
.ask-actions {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 1.75rem 0 1.5rem;
}
/* both CTAs take the mono face the rest of the deck's buttons use, so the
   closing slide reads as part of the same set rather than a web form.
   The secondary one is an <a download>, not a <button>, so the shared block
   also has to strip the anchor's underline and lay it out like a control. */
.btn-primary, .btn-secondary {
  font-family: var(--mono);
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  padding: 1.05rem 2rem;
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  text-decoration: none;
}
.btn-primary {
  position: relative;
  background: var(--gold);
  color: var(--navy-deep);
  border: none;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
/* a letterpress rule that draws itself in just outside the button on hover —
   the one flourish on the slide, borrowed from the deck's hairline dividers */
.btn-primary::before {
  content: "";
  position: absolute;
  inset: -5px;
  border: 1px solid var(--gold);
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}
.btn-primary .btn-arrow {
  font-size: 0.95rem;
  transition: transform 0.2s ease;
}
.btn-primary:hover, .btn-primary:focus-visible {
  background: var(--gold-soft);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(12,44,63,0.35);
}
.btn-primary:hover::before, .btn-primary:focus-visible::before {
  opacity: 0.55;
  transform: scale(1);
}
.btn-primary:hover .btn-arrow, .btn-primary:focus-visible .btn-arrow { transform: translateX(4px); }
.btn-primary:active { transform: translateY(0); box-shadow: none; }

.btn-secondary {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
  font-weight: 400;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.btn-secondary:hover, .btn-secondary:focus-visible { border-color: var(--gold); color: var(--gold); }
@media (prefers-reduced-motion: reduce) {
  .btn-primary,
  .btn-primary::before,
  .btn-primary .btn-arrow { transition: none; }
  .btn-primary:hover, .btn-primary:focus-visible { transform: none; }
  .consultation-btn,
  .consultation-btn::before,
  .consultation-btn svg { transition: none; }
  .consultation-btn:hover, .consultation-btn:focus-visible { transform: none; }
}
.terms-line {
  font-family: var(--mono);
  font-size: 0.85rem;
  color: var(--ink);
  letter-spacing: 0.03em;
  margin: 0 0 1.75rem;
}
/* cover-only placement: pulled out of the slide-inner flow and centered
   independently, sitting halfway between the subtitle's bottom edge and
   the slide's own bottom edge (measured live: subtitle bottom sits at
   59.5% of slide height, so 79.8% centers this line in the remaining
   gap) - a deliberate standalone statement, not a trailing caption under
   the subtitle. Bigger size to match that more prominent role. */
.appendix-link {
  background: none;
  border: none;
  color: var(--ink-dim);
  font-size: 0.85rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 0;
}
.appendix-link:hover, .appendix-link:focus-visible { color: var(--gold-soft); }

/* ---------- appendix ---------- */
.slide-appendix .slide-inner { max-width: 760px; }
.appendix-body {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  margin: 1.5rem 0 2rem;
  border-top: 1px solid var(--line);
  padding-top: 1.5rem;
}
.appendix-row h2 {
  font-family: var(--mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
  margin: 0 0 0.5rem;
  font-weight: 500;
}
.appendix-row p {
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin: 0;
  text-align: justify;
  text-justify: inter-word;
}

/* the policy links and social marks are the same components as the Terms &
   Socials drawer, relaid for the appendix's wider column: a row, not a stack,
   and the socials carry visible labels since there's room for them here */
/* .terms-links / .terms-socials are declared further down the file, so these
   overrides need the extra class to win rather than relying on source order */
.appendix-row .appendix-links {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.55rem 1.9rem;
  /* sits directly under its heading, so it takes the same gap the prose rows
     get from h2's own margin rather than adding a second one on top */
  margin: 0;
}
.appendix-row .appendix-links a { font-size: 0.85rem; }
.appendix-row .appendix-socials {
  gap: 1.75rem;
  flex-wrap: wrap;
  margin-top: 0;
}
.appendix-row .appendix-socials a {
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.82rem;
  text-decoration: none;
}
.appendix-row .appendix-socials svg { width: 17px; height: 17px; flex-shrink: 0; }

/* ---------- legal pages (terms, privacy, refund) ----------
   these scroll as documents rather than sitting in a 100vh slide box */
.legal-page {
  max-width: 760px;
  margin: 0 auto;
  /* top value cut down for the same reason as .pa-layout above - the sticky
     header is now always on screen, so the old clearance (tuned for a
     header that scrolled away) reads as permanent dead space. */
  padding: clamp(1.25rem, 3vw, 2rem) clamp(1.5rem, 5vw, 3rem) clamp(4rem, 10vw, 7rem);
}
/* central-column frosted panel, same recipe as .pa-main/.blog-container-
   article - one continuous panel behind the whole document instead of
   per-paragraph boxes. :not(.pa-footer) matters here: .legal-page is reused
   as the footer wrapper's own class on these same pages (terms/privacy/
   refund/sitemap/404, which all moved their footer out of the main content
   element specifically so it wouldn't get caught in this background) - the
   footer intentionally stays uncovered. */
.legal-page:not(.pa-footer) {
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 10px;
}
.legal-page .kicker { margin-bottom: 1rem; }
.legal-page .headline {
  max-width: none;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  margin-bottom: 0.75rem;
}

.legal-updated {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  margin: 0 0 2rem;
}

.legal-section { margin-bottom: 2rem; }
.legal-section h2 {
  font-family: var(--mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
  font-weight: 500;
  margin: 0 0 0.6rem;
}
.legal-section p,
.legal-section li {
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--ink-soft);
  margin: 0 0 0.85rem;
  text-align: justify;
  text-justify: inter-word;
}
.legal-section p:last-child,
.legal-section li:last-child { margin-bottom: 0; }
.legal-section ul {
  margin: 0 0 0.85rem;
  padding-left: 1.3rem;
}
.legal-section li { margin-bottom: 0.45rem; }
.legal-section a {
  color: var(--gold-soft);
  text-decoration: none;
  border-bottom: 1px solid rgba(242,201,76,0.4);
}
.legal-section a:hover, .legal-section a:focus-visible {
  color: var(--gold);
  border-bottom-color: var(--gold);
}

/* practice-area pages: widen past .legal-page's 760px reading width to fit
   Related/Recent insight sidebars either side of the prose, same 3-col
   recipe as .blog-post-layout. Footer sits in its own .legal-page wrapper
   below this grid so it keeps the narrower centered width instead of
   stretching to 1200px with the sidebars. */
.pa-layout {
  max-width: 1200px;
  margin: 0 auto;
  /* top value was tuned back when .blog-header scrolled away with the page -
     now that the header is sticky and permanently on screen, that same
     generous top clearance reads as dead space under a bar that's always
     there, so it's cut down considerably (was clamp(3rem, 8vw, 6rem)). */
  padding: clamp(1.25rem, 3vw, 2rem) clamp(1.5rem, 5vw, 3rem) 0;
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) 200px;
  gap: 2.5rem;
  align-items: start;
}
/* central reading column: one continuous, relatively translucent frosted
   panel behind the whole main column (not per-paragraph) - runs the full
   height of .pa-main, which naturally starts just under the sticky header
   and ends right before the footer, since it's the tallest thing in this
   grid row. Sidebars are deliberately left uncovered, so the constellation
   still reads clearly either side of the reading column. Unbordered, and
   lighter than the card fill (0.13) since this spans a much bigger area. */
.pa-main {
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 10px;
  padding: 2rem 2.2rem;
}
.pa-sidebar { position: sticky; top: calc(var(--sticky-header-h) + 2rem); }
/* right column: Related stacked above Recent, both inside one sticky
   grid-item wrapper (left column now holds the static Practice Areas
   list instead of Related, per the redesign) */
.pa-insights-stack #paRecent { margin-top: 2.5rem; }
/* same recipe as the slide .kicker (font, tracking, gold-on-azure color,
   stroke+shadow for legibility on the bright canvas) — applies to all three
   sidebar titles on practice-area pages ("Practice Areas", "Related",
   "Recent"), not blog-post pages' .blog-sidebar, which keeps its own
   quieter ink-faint treatment. */
.pa-sidebar .blog-sidebar-title {
  /* explicit normal weight matters here: "Practice Areas" is a <p> (already
     normal) but "Related"/"Recent" are <h2>s, which pick up the browser's
     bold heading default unless overridden - left implicit, the two looked
     like different treatments even at identical color. */
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--gold-on-azure);
  -webkit-text-stroke: 0.25px rgba(8, 20, 45, 0.3);
  text-shadow: 0 1px 2px rgba(4, 12, 28, 0.3);
}
/* .pa-main sits outside .legal-page now (the sidebars/footer restructure
   moved it into its own wrapper), so it lost .legal-page .headline's
   max-width:none override and fell back to the base .headline's 15ch cap
   — which wraps every practice-area title (e.g. "Cybersecurity & Privacy")
   onto two lines. Same override, just re-scoped to where the h1 lives now. */
.pa-main .headline {
  max-width: none;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  margin-bottom: 0.75rem;
}
/* "Emerging Companies & Venture Capital" is longer than the other five
   practice names, so at the shared size above it wraps to an ugly 3 lines
   ("Emerging / Companies & / Venture Capital"). Scaling it down lets it
   break the same way the others naturally do: clause "&" / clause. */
.pa-main .headline.pa-title-long {
  font-size: clamp(1.5rem, 3.3vw, 2.1rem);
}
/* per-area "book a call" CTA — sits between the Common Agreements section
   and the Browse-articles/back-link pair. Reuses .btn-primary (the same
   "Book a call" button consult.html already uses, same Calendly link)
   rather than inventing a new CTA style, so a visitor sees one consistent
   button sitewide regardless of which page convinced them to click it. */
.pa-cta {
  border-top: 1px solid var(--line);
  padding-top: 1.75rem;
  margin: 0 0 2rem;
}
.pa-cta-line { margin-bottom: 1.25rem; }
@media (max-width: 980px) {
  .pa-cta { padding-top: 1.5rem; }
}
/* FAQ block — native <details>/<summary> disclosure, no JS, matching the
   site's existing preference for plain HTML/CSS interaction where possible
   (see blog-archive.js's filter/search: "no JS required"). Hairline
   dividers between items, same language as .mt-card-docs/.pa-cta rather
   than a bordered-box accordion. The +/− marker is plain mono text, not an
   icon font or SVG, so it never needs its own asset. */
.pa-faq details {
  border-top: 1px solid var(--line);
  padding: 1.1rem 0;
}
.pa-faq details:last-of-type { padding-bottom: 0; }
.pa-faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
}
.pa-faq summary::-webkit-details-marker { display: none; }
.pa-faq summary::after {
  content: "+";
  font-family: var(--mono);
  font-size: 0.95rem;
  color: var(--gold-soft);
  flex-shrink: 0;
}
.pa-faq details[open] summary::after { content: "\2212"; }
.pa-faq details[open] summary { color: var(--gold-bright); }
/* not justified, unlike .legal-section's default body copy — a short
   FAQ answer at this block width reads better ragged-right than with the
   uneven word-spacing justification can introduce on short lines. */
.pa-faq details p {
  margin: 0.85rem 0 0;
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--ink-dim);
  text-align: left;
}
/* zeroes .legal-page's own top padding when it's reused as the footer
   wrapper below .pa-layout, so the two don't stack into a double gap */
.legal-page.pa-footer { padding-top: 0; }
@media (max-width: 980px) {
  .pa-layout { grid-template-columns: 1fr; }
  .pa-sidebar { position: static; }
  .pa-main { order: 1; }
  .pa-insights-stack { order: 2; margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--line); }
  #paPracticeAreas { order: 3; margin-top: 2.5rem; }
}

.legal-footer {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.legal-footer a {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--ink-dim);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.legal-footer a:hover, .legal-footer a:focus-visible {
  color: var(--gold-soft);
  border-bottom-color: var(--gold);
}
.legal-footer a[aria-current="page"] {
  color: var(--gold-soft);
  border-bottom-color: var(--gold);
}

/* ---------- intake form (contact.html) ---------- */
.intake-form { margin-top: 2rem; }
.intake-field { margin-bottom: 1.4rem; }
.intake-field label {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin-bottom: 0.5rem;
}
.intake-field-optional {
  font-normal: normal;
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.75;
}
.intake-field input[type="text"],
.intake-field input[type="email"],
.intake-field textarea,
.intake-field select {
  width: 100%;
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.92rem;
  padding: 0.8rem 0.9rem;
  border-radius: 3px;
}
.intake-field textarea { resize: vertical; min-height: 120px; }
/* the closed select box picks up the frosted styling above fine, but its
   dropdown *options* list is a separate native OS popup that ignores
   background/backdrop-filter entirely - browsers that do honor a plain
   background-color/color on <option> (Chromium, Firefox) get this instead
   of the default white/black; Safari still won't, no CSS-only fix for that. */
.intake-field select option {
  background: var(--azure-bright-deep);
  color: var(--ink);
}
.intake-field input::placeholder,
.intake-field textarea::placeholder { color: var(--ink-dim); opacity: 1; }
.intake-field input:focus,
.intake-field textarea:focus,
.intake-field select:focus { outline: none; border-color: var(--azure-bright); }
/* the honeypot: present in the DOM (so a bot's form-fill script finds and
   fills it) but invisible and unreachable to a real visitor or screen
   reader/keyboard user. */
.intake-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.intake-consent {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  margin: 1.6rem 0 1.8rem;
}
.intake-consent input[type="checkbox"] {
  margin-top: 0.2rem;
  flex-shrink: 0;
}
.intake-consent label {
  font-size: 0.84rem;
  line-height: 1.55;
  color: var(--ink-dim);
}
.intake-submit {
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.intake-recaptcha-note {
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--ink-faint);
  margin: 0 0 1.4rem;
}
.intake-recaptcha-note a { color: var(--ink-faint); text-decoration: underline; }
.intake-recaptcha-note a:hover, .intake-recaptcha-note a:focus-visible { color: var(--gold); }
.intake-status {
  margin-top: 1.2rem;
  font-size: 0.88rem;
  line-height: 1.6;
}
.intake-status.is-success { color: var(--gold-soft); }
.intake-status.is-error { color: #E8845F; }

/* ---------- notes drawer ---------- */
/* .notes-block itself is unused now — deck.js reparents .notes-drawer out of
   it and into .bottom-controls (see the comment there), the same fix
   .terms-drawer already relied on. Left in the markup harmlessly empty. */

.notes-toggle {
  background: rgba(244,241,232,0.05);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-size: 0.78rem;
  font-family: var(--mono);
  line-height: 1;
  padding: 0.55rem 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  letter-spacing: 0.03em;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.notes-toggle:hover, .notes-toggle:focus-visible {
  border-color: var(--gold);
  color: var(--gold-soft);
  background: rgba(242,201,76,0.1);
}
.notes-toggle:disabled { opacity: 0.35; pointer-events: none; }
.notes-icon { font-size: 0.85rem; }

.notes-drawer {
  /* same technique as .terms-drawer just above: absolute against
     .bottom-controls (position:fixed, now its real containing block),
     opening directly above the row instead of near wherever the card
     happened to place it. right:-180px (not flush right:0, and not left:0
     like .terms-drawer) shifts the whole box further right, growing past
     the Notes button's own right edge into the open space beyond the
     toolbar, instead of stopping exactly at the button and only ever
     growing left back across Consultation/Terms. */
  position: absolute;
  right: -180px;
  bottom: calc(100% + 0.75rem);
  z-index: 31;
  max-width: min(480px, 88vw);
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 1.1rem 1.25rem;
  text-align: left;
  max-height: min(48vh, 440px);
  overflow-y: auto;
}
/* .bottom-controls > * (below) sets nowrap for the toolbar's own button
   labels, and — same specificity, later in the file — wins over a plain
   ".notes-drawer" override regardless of source position. ".bottom-controls
   .notes-drawer" (specificity 0,2,0) outranks ".bottom-controls > *"
   (0,1,0) outright. Without this the drawer's paragraphs refuse to wrap at
   all, growing the box to the text's full unwrapped width. */
.bottom-controls .notes-drawer { white-space: normal; }
.notes-drawer p {
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.7;
  color: var(--ink-dim);
  margin: 0 0 0.9rem;
  /* hyphenation keeps the gaps in check — justified monospace in a ~380px
     column opens up rivers of whitespace without it */
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.notes-drawer p:last-child { margin-bottom: 0; }

/* ---------- nav arrows ---------- */
.deck-nav { position: fixed; inset: 0; pointer-events: none; z-index: 40; }
.nav-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(244,241,232,0.05);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.nav-arrow svg { width: 20px; height: 20px; }
.nav-arrow:hover, .nav-arrow:focus-visible {
  background: rgba(242,201,76,0.12);
  border-color: var(--gold);
  color: var(--gold-soft);
}
.nav-arrow { text-decoration: none; }
.nav-prev { left: clamp(0.75rem, 2.5vw, 2rem); }
.nav-next { right: clamp(0.75rem, 2.5vw, 2rem); }

/* ---------- chrome: counter, grid button, version stamp ---------- */
.slide-counter {
  position: fixed;
  left: clamp(1.25rem, 3vw, 2rem);
  bottom: clamp(1.25rem, 3vw, 2rem);
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  letter-spacing: 0.05em;
  z-index: 30;
  transition: color 0.2s ease;
  /* it's a button now — strip the UA chrome, keep the plain-text look */
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  line-height: 1;
}
.slide-counter svg { width: 13px; height: 13px; }
.slide-counter:hover, .slide-counter:focus-visible { color: var(--gold-soft); }

.bottom-controls > * { white-space: nowrap; }

.bottom-controls {
  position: fixed;
  bottom: clamp(1.25rem, 3vw, 2rem);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  z-index: 30;
}

.consultation-btn {
  position: relative;
  background: rgba(242,201,76,0.08);
  border: 1px solid rgba(242,201,76,0.4);
  color: var(--gold-soft);
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1;
  padding: 0.55rem 1.1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
/* same letterpress-ring + lift treatment as .btn-primary (the "Book a call"
   CTA), scaled down to fit this smaller pill */
.consultation-btn::before {
  content: "";
  position: absolute;
  inset: -4px;
  border: 1px solid var(--gold);
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}
.consultation-btn svg { width: 14px; height: 14px; transition: transform 0.2s ease; }
.consultation-btn:hover, .consultation-btn:focus-visible {
  border-color: var(--gold);
  color: var(--gold);
  background: rgba(242,201,76,0.16);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(12,44,63,0.35);
}
.consultation-btn:hover::before, .consultation-btn:focus-visible::before {
  opacity: 0.55;
  transform: scale(1);
}
.consultation-btn:hover svg, .consultation-btn:focus-visible svg { transform: translateX(2px); }
.consultation-btn:active { transform: translateY(0); box-shadow: none; }

/* ---------- terms & socials ---------- */
.terms-toggle {
  background: rgba(244,241,232,0.05);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-family: var(--mono);
  font-size: 0.72rem;
  line-height: 1;
  padding: 0.55rem 1.1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  letter-spacing: 0.03em;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.terms-toggle svg { width: 14px; height: 14px; }
.terms-toggle:hover, .terms-toggle:focus-visible {
  border-color: var(--gold);
  color: var(--gold-soft);
  background: rgba(242,201,76,0.1);
}

.terms-drawer {
  position: absolute;
  bottom: calc(100% + 0.75rem);
  left: 0;
  z-index: 31;
  width: min(90vw, 260px);
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 1rem 1.25rem;
  text-align: left;
  white-space: normal;
}
.terms-drawer[hidden] { display: none; }

.terms-drawer-heading {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 0.6rem;
}
.terms-drawer-heading + * { margin-top: 0; }

.terms-links {
  list-style: none;
  margin: 0 0 1.1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.terms-links a {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-dim);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.terms-links a:hover, .terms-links a:focus-visible {
  color: var(--gold-soft);
  border-bottom-color: var(--gold);
}

.terms-socials {
  display: flex;
  gap: 0.9rem;
}
.terms-socials a {
  color: var(--ink-dim);
  display: inline-flex;
  transition: color 0.2s ease, transform 0.2s ease;
}
.terms-socials svg { width: 18px; height: 18px; }
.terms-socials a:hover, .terms-socials a:focus-visible {
  color: var(--gold-soft);
  transform: translateY(-2px);
}

/* ---------- grid / zoom-out view ---------- */
/* same dark "stage" backdrop as the real slide's ambient page background
   (body:has(main.slide), ~line 124) instead of a flat navy-deep fill, so
   the overlay reads as the same room the slides themselves sit in. */
.grid-overlay {
  position: fixed;
  inset: 0;
  /* bright azure, matching the real .slide canvas - the "view all slides"
     overlay used to keep the old dark navy backdrop even after every real
     slide moved to azure, so its own thumbnails looked like a different,
     older version of the deck. */
  background: radial-gradient(circle at center, var(--azure-bright-light) 0%, var(--azure-bright-mid) 45%, var(--azure-bright-deep) 100%);
  z-index: 100;
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
  transition: opacity 0.4s cubic-bezier(.4,0,.2,1), transform 0.4s cubic-bezier(.4,0,.2,1);
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 3rem);
}
.grid-overlay.is-open {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}
/* room so the last row never sits under the floating back button */
.grid-overlay { padding-bottom: 6rem; }

.grid-back-btn {
  position: fixed;
  bottom: clamp(1.25rem, 3vw, 2rem);
  left: 50%;
  transform: translateX(-50%);
  background: rgba(244,241,232,0.05);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-size: 0.78rem;
  line-height: 1;
  padding: 0.55rem 1.1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  z-index: 110;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.grid-back-btn[hidden] { display: none; }
.grid-back-btn svg { width: 14px; height: 14px; }
.grid-back-btn:hover, .grid-back-btn:focus-visible {
  border-color: var(--gold);
  color: var(--gold);
  background: rgba(242,201,76,0.1);
}
.grid-overlay-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 1200px;
  margin: 0 auto 2rem;
}
.grid-overlay-title {
  font-family: var(--serif);
  font-size: 1.4rem;
  color: var(--ink);
  margin: 0;
}
.grid-close {
  background: none;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.grid-close svg { width: 16px; height: 16px; }
.grid-close:hover, .grid-close:focus-visible { border-color: var(--gold); color: var(--gold-soft); }

.grid-wrap {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
}
@media (max-width: 640px) {
  .grid-wrap { grid-template-columns: repeat(2, 1fr); }
}
/* same gradient recipe as the real .slide card (~line 149: navy-panel to
   navy to navy-deep, 155deg), skipping that card's two corner-highlight
   radial gradients (not enough surface area to read at thumbnail scale),
   plus a matching rounded corner and a light version of its drop shadow,
   so each thumbnail reads as a small lit slide rather than a flat tile. */
.grid-thumb {
  aspect-ratio: 16/10;
  /* frosted glass, same recipe as every deck card - a translucent lift off
     the bright azure backdrop rather than a navy fill, so each thumbnail
     matches the actual current card style instead of the old dark theme. */
  background: var(--deck-card-fill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--deck-card-border);
  border-radius: 8px;
  box-shadow: 0 10px 24px rgba(0,0,0,0.35);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding: 1.1rem;
  text-align: left;
  text-decoration: none;
  transition: border-color 0.2s ease, transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
/* the page you're already on */
.grid-thumb.is-current {
  border-color: #FFFFFF;
  background: rgba(255,255,255,0.24);
}
.grid-thumb:hover, .grid-thumb:focus-visible {
  border-color: var(--gold);
  transform: translateY(-3px);
  background: rgba(255,255,255,0.22);
  box-shadow: 0 0 16px rgba(242,201,76,0.25), 0 10px 24px rgba(0,0,0,0.35);
}
.grid-thumb-num {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--gold);
}
.grid-thumb-title {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.3;
}
.grid-thumb-appendix {
  border-style: dashed;
  opacity: 0.8;
}
.grid-thumb-appendix .grid-thumb-num { color: var(--gold-soft); }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 5.5rem;
  transform: translate(-50%, 12px);
  background: var(--deck-card-fill);
  border: 1px solid var(--gold);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--ink);
  font-size: 0.85rem;
  padding: 0.75rem 1.25rem;
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
  max-width: min(420px, 88vw);
  text-align: center;
}
.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ================= MOBILE ================= */
/* "screen and" is load-bearing, not decoration. Chromium resolves width media
   queries in print against the page box in points - a 210mm page is ~595pt,
   under this 768px breakpoint - so an unscoped query applies the entire mobile
   stylesheet to the PDF export: every multi-column grid collapses to one
   column and the slides overflow their page. */
@media screen and (max-width: 768px) {
  .slide {
    display: block;
    width: min(97vw, 480px);
    margin: 0.6rem auto;
    min-height: calc(100vh - 1.2rem);
    border-radius: 8px;
    padding: 5rem 1.5rem 9rem;
  }

  .slide-cover {
    width: min(97vw, 480px);
    aspect-ratio: auto;
    min-height: calc(100vh - 1.2rem);
  }

  /* arrows stay visible on mobile — each page is now a real page, so they are
     the only way forward (the old vertical scroll-stack no longer applies) */
  .nav-arrow { width: 38px; height: 38px; }
  .nav-arrow svg { width: 16px; height: 16px; }
  .nav-prev { left: 0.5rem; }
  .nav-next { right: 0.5rem; }

  .bottom-controls {
    bottom: 1rem;
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: center;
    width: min(94vw, 480px);
  }
  .bottom-controls .consultation-btn,
  .bottom-controls .terms-toggle,
  .bottom-controls .notes-toggle {
    font-size: 0.7rem;
    padding: 0.5rem 0.75rem;
  }
  /* the counter is the grid trigger now, so it has to stay reachable here —
     it moves up out of the way of the controls rather than being hidden */
  .slide-counter { bottom: auto; top: 1rem; right: 1rem; left: auto; font-size: 0.7rem; }

  /* the desktop -70px right offset (pushing the drawer past the Notes
     button into open space) runs the box off the right edge of a narrow
     mobile viewport instead — .bottom-controls itself is width-capped and
     centered here, so flush-right is the safe, reachable position. */
  .notes-drawer { right: 0; max-width: min(300px, 82vw); }

  .card-grid,
  .tier-grid,
  .practice-columns { grid-template-columns: 1fr; }
  /* five equal columns of a single mono word each is fine at 980px, but at
     375px "GOVERNANCE" has nowhere to go — stack them like the stage
     spectrum on the client-fit slide does at the same breakpoint */
  .svc-tabs { flex-direction: column; gap: 0.4rem; padding-bottom: 0; }
  .svc-tab { justify-content: flex-start; padding: 0.65rem 0.85rem; }
  .svc-tab::after { left: 0; right: 0; bottom: -1px; }
  /* stacked, there are no columns left to align, so the shared row lines go
     away and the cards need their vertical gap back — enough of it to clear
     the "most clients" / "you are here" flag hanging off the top edge */
  .tier-grid { row-gap: 1.4rem; }
  /* the stage spectrum reads better as a stack than as five squeezed
     mono labels on a 375px screen */
  .cf-stage-band { flex-direction: column; gap: 0.4rem; }
  .cf-stage-seg { height: auto; padding: 0.6rem 0; }
  /* There is no hover on touch, and a floating layer would cover the
     segments stacked underneath it. So the note drops into normal flow
     inside its own segment instead — otherwise these two sentences would
     be unreachable on a phone. */
  .cf-stage-seg[data-note] {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.75rem 0.85rem;
  }
  .cf-stage-seg[data-note]::after,
  .cf-stage-seg[data-note]:hover::after {
    content: attr(data-note);
    position: static;
    width: auto;
    background: none;
    border: none;
    box-shadow: none;
    padding: 0;
    color: var(--ink-dim);
    font-family: var(--sans);
    font-size: 0.78rem;
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.55;
    text-align: left;
    hyphens: manual;
  }
  .cf-stage-foot { flex-direction: column; align-items: flex-start; gap: 0.4rem; }
  .cf-map { grid-template-columns: 1fr; row-gap: 1.4rem; }
  /* dropping the span without also dropping the subgrid left each card with
     a single row to place four children into, so they all painted on top of
     one another — stacked, there are no columns left to align anyway */
  .cf-tier { grid-row: auto; grid-template-rows: auto; }
}

/* ---------- standalone blog pages (/blog, /blog/:slug) ----------
   Server-rendered by Netlify Functions, outside the deck.js slide chrome —
   no prev/next arrows, no slide counter, no keyboard slide nav. Reuses the
   same :root palette/fonts and the .insight-* card language from the deck's
   Insights slide so it still feels like the same site. */
.blog-shell { min-height: 100vh; display: flex; flex-direction: column; }
.blog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  padding: 1.5rem clamp(1.25rem, 4vw, 3rem);
  border-bottom: 1px solid var(--line);
  /* stays visible while the page scrolls, on every non-deck page (blog,
     legal, practice-area, admin) this header appears on. Rather than a
     distinct frosted-glass panel, it carries the exact same background
     layers as html,body (same image/position/size, both fixed-attachment)
     so it reads as one continuous canvas the header just sits on top of -
     opaque enough to occlude scrolling content, but visually identical to
     the page background rather than a separate bar dropped over it.
     z-index sits below the nav drawer/backdrop (60/61) so opening the menu
     still overlays this correctly. */
  position: sticky;
  top: 0;
  z-index: 40;
  background-image:
    url("/brand-assets/patterns/constellation-network.svg"),
    url("/brand-assets/patterns/medallion-mark.svg"),
    radial-gradient(ellipse 60% 45% at 15% -10%, rgba(255, 255, 255, 0.09), transparent 60%),
    radial-gradient(ellipse 55% 50% at 105% 115%, rgba(242, 201, 76, 0.09), transparent 60%),
    linear-gradient(155deg, var(--azure-bright-light) 0%, var(--azure-bright-mid) 45%, var(--azure-bright-deep) 100%);
  background-position: -6% -8%, var(--medallion-pos), 0 0, 0 0, 0 0;
  background-size: 135% 135%, 34%, auto, auto, auto;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
.blog-logo {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.blog-logo-azure { background: var(--gold); color: var(--azure-bright); padding: 0.02em 0.14em; }
.blog-logo-legal { color: #FFFFFF; margin-left: 0.15em; }
.blog-nav-back {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-dim);
  text-decoration: none;
  border: 1px solid var(--line);
  padding: 0.5rem 0.9rem;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.blog-nav-back:hover, .blog-nav-back:focus-visible { border-color: var(--gold); color: var(--gold); }
/* sitewide header nav — used on every standalone page (blog + legal +
   practice-area pages), not just /blog. Down to a single Contact link now
   that the burger/drawer below covers the rest of the site (Practice
   Areas/Insights used to live here too). Kept as its own nav/class rather
   than collapsing into a plain link, in case a second header action gets
   added later. */
.blog-header-nav {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.blog-header-nav .blog-nav-back { padding: 0.5rem 0.8rem; }
/* groups the new burger button with the logo on the header's left side,
   so .blog-header's existing justify-content: space-between still pushes
   the lone Contact link to the right. */
.blog-header-left {
  display: flex;
  align-items: center;
  gap: 1rem;
}
/* classic hamburger icon — opens .site-nav-drawer (below). Same bordered-
   box hover language as .blog-nav-back rather than a borderless icon, so
   it reads as clickable alongside the logo without a label. */
.site-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem;
  height: 2.3rem;
  flex-shrink: 0;
  background: none;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.site-nav-toggle svg { width: 1.1rem; height: 1.1rem; }
.site-nav-toggle:hover, .site-nav-toggle:focus-visible { border-color: var(--gold); color: var(--gold); }

/* deck pages only: the burger has no header to sit inline in, so it's
   fixed to the viewport at the same top-left inset the deck's other
   chrome uses (nav-prev/slide-counter) — outside the framed slide card
   in theatre mode (>=769px), same reasoning documented on nav-arrow/
   slide-counter for why this chrome lives outside .slide entirely. */
.deck-nav-toggle {
  position: fixed;
  top: clamp(1.25rem, 3vw, 2rem);
  left: clamp(1.25rem, 3vw, 2rem);
  z-index: 50;
  /* subtle translucent ink wash, matching .nav-arrow's floating-chrome
     recipe, rather than .site-nav-toggle's transparent default (which
     relies on a solid header background for contrast the deck doesn't have) */
  background: rgba(244,241,232,0.05);
}
@media (max-width: 640px) {
  /* the base top-left inset only collides with the cover slide's
     .ad-stamp specifically (no stage margin once the fixed-canvas theatre
     mode drops out below 769px) — every other slide's kicker starts
     further down, clear of the default position, so this scopes the
     drop-down to the cover only rather than moving it on every slide.
     body:has(), same pattern already used for the theatre-mode wrapper. */
  body:has(.slide-cover) .deck-nav-toggle { top: 4.5rem; }
}

/* ---------- site nav drawer ----------
   Slide-in panel, reachable from every standalone page via the burger
   button — a curated two-column shortlist (Pitch Deck / Explore), not the
   exhaustive /sitemap list. Sans (Inter) rather than the mono/uppercase
   treatment used for labels/tags everywhere else on the site — reads
   calmer and more editorial, closer to a boutique firm's own site nav
   than a piece of deck chrome. The panel itself carries a soft shadow
   (rather than just the flat right-border it had before) so it reads as
   a floating premium surface. */
.site-nav-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(5, 12, 20, 0.6);
  z-index: 60;
}
.site-nav-backdrop[hidden] { display: none; }
.site-nav-drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 61;
  /* Sized to what the two columns actually need (measured: ~162px/171px
     of content each at this font-size) plus padding/gap, not a round
     number with slack — the drawer's job is quick navigation, not
     covering the page underneath it. */
  width: min(88vw, 460px);
  overflow-y: auto;
  background: var(--azure-bright);
  border-right: 1px solid var(--line);
  box-shadow: 12px 0 40px rgba(0,0,0,0.35);
  padding: 1.5rem;
}
.site-nav-drawer[hidden] { display: none; }
.site-nav-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
}
.site-nav-close {
  background: none;
  border: none;
  color: var(--ink-dim);
  font-size: 1.6rem;
  line-height: 1;
  padding: 0.2rem 0.4rem;
  cursor: pointer;
  transition: color 0.2s ease;
}
.site-nav-close:hover, .site-nav-close:focus-visible { color: var(--gold); }
.site-nav-columns {
  display: grid;
  /* max-content, not 1fr 1fr — each column hugs its own longest link
     instead of stretching to split the drawer's width evenly (which
     padded out empty space on the shorter "Pitch Deck" column). */
  grid-template-columns: max-content max-content;
  align-items: start;
  gap: 1.25rem;
}
@media (max-width: 560px) {
  .site-nav-columns { grid-template-columns: 1fr; gap: 1.75rem; }
}
/* same divider language .practice-col-docs already uses for the same
   shape of layout (two lists side by side) elsewhere on the site. Divider
   padding is on top of the grid gap above, not doubled with it — an
   earlier 3rem+3rem combination put ~6rem of dead space between columns,
   part of why the drawer needed to be so wide. */
.site-nav-col + .site-nav-col {
  border-left: 1px solid var(--line);
  padding-left: 1.25rem;
}
@media (max-width: 560px) {
  .site-nav-col + .site-nav-col { border-left: none; padding-left: 0; }
}
.site-nav-heading {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 1.1rem;
  white-space: nowrap;
}
.site-nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.site-nav-list a {
  font-family: var(--sans);
  font-size: 0.94rem;
  line-height: 1.3;
  color: var(--ink);
  text-decoration: none;
  /* Most labels are short enough to sit on one line at their natural
     width, which is what let the columns use max-content sizing below.
     "Emerging Companies & Venture Capital" is long enough to blow past
     every other label's width, so wrapping (capped by max-width) is
     allowed rather than forcing the drawer wider to fit one label.
     max-width has no effect on an inline element, hence inline-block -
     unlike block, inline-block still shrinks to the actual text width on
     every line that doesn't need to wrap, so the hover/focus underline
     below keeps hugging real text instead of stretching to the full
     195px cap. The longest surviving single-line label
     ("02 - The Problem/Solution") measures ~185px, hence that cap. */
  display: inline-block;
  white-space: normal;
  max-width: 195px;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.site-nav-list a:hover, .site-nav-list a:focus-visible {
  color: var(--gold-soft);
  border-bottom-color: var(--gold);
}
.site-nav-socials {
  display: flex;
  gap: 1rem;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.site-nav-socials a { color: var(--ink-dim); display: inline-flex; transition: color 0.2s ease, transform 0.2s ease; }
.site-nav-socials svg { width: 17px; height: 17px; }
.site-nav-socials a:hover, .site-nav-socials a:focus-visible {
  color: var(--gold-soft);
  transform: translateY(-2px);
}
/* top padding cut down from the shared clamp(2rem,5vw,4rem) - same reason as
   .pa-layout/.legal-page above, now that .blog-header stays on screen. */
.blog-main { flex: 1; padding: clamp(1.25rem, 3vw, 2rem) clamp(1.25rem, 4vw, 3rem) clamp(2rem, 5vw, 4rem); }
.blog-container { max-width: 1040px; margin: 0 auto; width: 100%; }
/* same central-reading-column treatment as .pa-main on the practice pages -
   one continuous, relatively translucent frosted panel behind the whole
   article column instead of per-paragraph boxes, running from just under
   the sticky header to just above the footer. Sidebars stay uncovered. */
.blog-container-article {
  max-width: 720px;
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 10px;
  padding: 2rem 2.2rem;
}
.blog-eyebrow {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-bright);
  margin: 0 0 1rem;
}
.blog-h1 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  line-height: 1.2;
  margin: 0 0 1rem;
}
.blog-lede { font-size: 1rem; color: var(--ink-dim); max-width: 60ch; margin: 0 0 2rem; }
.blog-search {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 420px;
  margin: 0 0 1.5rem;
}
.blog-search input[type="text"] {
  flex-grow: 1;
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.6rem 0.8rem;
}
.blog-search input[type="text"]:focus { outline: none; border-color: var(--azure-bright); }
.blog-search input[type="text"]::placeholder { color: var(--ink-dim); opacity: 1; }
.blog-search button {
  background: var(--gold);
  color: var(--navy-deep);
  border: none;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.6rem 1.1rem;
  flex: none;
}
.blog-search button:hover { background: var(--gold-soft); }
.blog-search-clear {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  text-decoration: none;
  flex: none;
  transition: color 0.2s ease;
}
.blog-search-clear:hover, .blog-search-clear:focus-visible { color: var(--gold); }
.blog-byline {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin: 0 0 0.6rem;
}
/* the author name is a real link (to /team) when a profile mapping exists -
   left unstyled it fell back to the browser's default link blue instead of
   inheriting the byline's own gold. */
.blog-byline a { color: inherit; text-decoration: none; }
.blog-byline a:hover, .blog-byline a:focus-visible { color: var(--gold-bright); text-decoration: underline; }
.blog-post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}
/* ---------- individual post: related/recent sidebars ---------- */
.blog-post-layout {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) 200px;
  gap: 2.5rem;
  align-items: start;
}
.blog-sidebar { position: sticky; top: calc(var(--sticky-header-h) + 2rem); }
.blog-sidebar-title {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
}
.blog-side-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1.1rem; }
.blog-side-card { display: flex; flex-direction: column; gap: 0.3rem; text-decoration: none; }
.blog-side-card-title { font-family: var(--serif); font-size: 0.92rem; line-height: 1.35; color: var(--ink); transition: color 0.2s ease; }
.blog-side-card-date { font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); }
.blog-side-card:hover .blog-side-card-title, .blog-side-card:focus-visible .blog-side-card-title { color: var(--gold); }
@media (max-width: 980px) {
  .blog-post-layout { grid-template-columns: 1fr; }
  .blog-sidebar { position: static; }
  .blog-sidebar-related { order: 2; margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--line); }
  .blog-container-article { order: 1; }
  .blog-sidebar-recent { order: 3; margin-top: 2.5rem; }
}

/* ---------- individual post: comments ---------- */
.blog-comments { margin-top: 3.5rem; padding-top: 2.5rem; border-top: 1px solid var(--line); }
.blog-comments-title { font-family: var(--serif); font-weight: 600; font-size: 1.3rem; margin: 0 0 1.5rem; }
.blog-comments-list { display: flex; flex-direction: column; gap: 1.25rem; margin-bottom: 2rem; }
.blog-comment {
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 8px;
  padding: 1rem 1.2rem;
}
.blog-comment-meta {
  display: flex;
  gap: 0.8rem;
  align-items: baseline;
  margin: 0 0 0.5rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.blog-comment-name { color: var(--gold-soft); }
.blog-comment-date { color: var(--ink-faint); }
.blog-comment-text { margin: 0; font-size: 0.9rem; line-height: 1.6; color: var(--ink-dim); white-space: pre-wrap; }
.blog-comments-empty { color: var(--ink-faint); font-size: 0.9rem; margin: 0 0 2rem; }
.blog-comment-form {
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 8px;
  padding: 1.5rem;
}
.blog-comment-field { margin-bottom: 1rem; }
.blog-comment-field label {
  display: block;
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  margin-bottom: 0.4rem;
}
.blog-comment-field input[type="text"],
.blog-comment-field textarea {
  width: 100%;
  background: var(--deck-card-fill);
  border: 1px solid var(--deck-card-border);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.65rem 0.75rem;
}
.blog-comment-field input::placeholder,
.blog-comment-field textarea::placeholder { color: var(--ink-dim); opacity: 1; }
.blog-comment-field textarea { min-height: 100px; resize: vertical; }
.blog-comment-field input:focus, .blog-comment-field textarea:focus { outline: none; border-color: var(--azure-bright); }
.blog-comment-note { font-size: 0.76rem; color: var(--ink-faint); margin: 0 0 1rem; }
.blog-comment-form button {
  background: var(--gold);
  color: var(--navy-deep);
  border: none;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.7rem 1.4rem;
}
.blog-comment-form button:hover { background: var(--gold-soft); }
.blog-comment-form button:disabled { opacity: 0.6; cursor: default; }
.blog-comment-status { margin: 0.8rem 0 0; font-size: 0.82rem; color: var(--azure-bright); min-height: 1.2em; }

.blog-tags a { color: inherit; text-decoration: none; }
.blog-tags a:hover, .blog-tags a:focus-visible { color: var(--gold-soft); }
.blog-tags {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 2.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
.blog-article { font-size: 1rem; line-height: 1.75; color: var(--ink-soft); }
.blog-article h2 { font-family: var(--serif); font-weight: 600; font-size: 1.4rem; color: var(--ink); margin: 2rem 0 0.85rem; }
.blog-article h3 { font-family: var(--serif); font-weight: 600; font-size: 1.15rem; color: var(--ink); margin: 1.75rem 0 0.7rem; }
.blog-article p { margin: 0 0 1.15rem; }
.blog-article ul, .blog-article ol { margin: 0 0 1.15rem; padding-left: 1.4rem; }
.blog-article li { margin-bottom: 0.4rem; }
.blog-article blockquote {
  margin: 0 0 1.15rem;
  padding-left: 1rem;
  border-left: 2px solid var(--gold);
  color: var(--ink-dim);
  font-style: italic;
}
.blog-article a { color: var(--azure-bright); }
.blog-article hr { border: none; border-top: 1px solid var(--line); margin: 1.75rem 0; }
.blog-footer {
  padding: 2rem clamp(1.25rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
  text-align: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
}
.blog-footer a { color: var(--ink-faint); }
.blog-footer a:hover { color: var(--gold); }
.blog-footer-socials { display: flex; gap: 0.8rem; }
.blog-footer-socials a { color: var(--ink-faint); display: inline-flex; transition: color 0.2s ease, transform 0.2s ease; }
.blog-footer-socials svg { width: 16px; height: 16px; }
.blog-footer-socials a:hover, .blog-footer-socials a:focus-visible {
  color: var(--gold-soft);
  transform: translateY(-2px);
}
.blog-footer-disclaimer {
  margin: 0.6rem 0 0;
  font-size: 0.62rem;
  letter-spacing: 0.03em;
  color: var(--ink-faint);
  opacity: 0.75;
}
.blog-pagination {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.5rem;
  font-family: var(--mono);
  font-size: 0.8rem;
}
.blog-pagination a {
  color: var(--gold-soft);
  text-decoration: none;
  border: 1px solid var(--line);
  padding: 0.55rem 1rem;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.blog-pagination a:hover, .blog-pagination a:focus-visible { border-color: var(--gold); color: var(--gold); }
.blog-empty { color: var(--ink-faint); padding: 3rem 0; text-align: center; }
.blog-404-code { font-family: var(--mono); color: var(--gold-bright); font-size: 0.85rem; letter-spacing: 0.1em; }
