/* ============================================================================================
   ITG BLOCKS — section shells, colour bands and two-column rows.
   Depends on tokens.css + primitives.css. Load LAST.

   Section rhythm: seam between two sections = bottom pad of one + top pad of the next.
     --sec-pad   between sections that share a background
     --zone-pad  clearance from a COLOUR-ZONE edge. Bigger on purpose: the band change is a hard
                 visual break, so content must not crowd it.
     --sec-group sections that must read as ONE unit (video + episodes)
   Extracted from index.html 2026-08-14.
   ============================================================================================ */

/* white band: Video -> Episodes (dark text on white, full-bleed over the grid, no dot grid) */
    .itg-light{background:#ffffff;position:relative;z-index:5;}

.itg-light h2{color:#1b242a !important;}

/* LIGHT-CONTEXT BODY (2026-08-13, Nico). Two compensations, both deliberate:
       colour at full strength (a mirrored .75 alpha read washed: 6.91:1 vs the dark side's
       20.28:1), and weight 400 -> 600 to offset irradiation — light-on-dark type expands
       optically, dark-on-light contracts, so the same weight reads thinner here.
       600 because Titillium Web has NO 500: Google Fonts serves 200/300/400/600/700/900
       only, and asking for 500 gets a synthesised fake. Verified against the API. */
    .itg-light p{color:#1b242a !important;font-weight:600;}

/* eyebrows: ITG cyan is unreadable on white -> ITG Blue (light-bg primary) */
    .itg-light .eyebrow{color:#0661aa !important;}

/* ══ CTA band ══ full-bleed gradient across the whole section (2026-08-13, Nico) ═══ */
    .itg-cta{position:relative;z-index:5;background:linear-gradient(135deg,#00a8ba 0%,#00374a 50%,#04060a 100%);}

/* ACCENTED TYPE ON THE GRADIENT IS WHITE, not lime. Third context to need the --accent /
   --accent-text split, and for the same reason as the white band: --accent is a GRAPHIC colour
   (the CTA's lime button keeps it and measures 16.03:1 against its ink label) but lime TYPE does
   not survive the bright end of this ramp.
   Measured 2026-08-14 on subscribe.html, whose tall CTA band puts body copy over the #00a8ba end:
   lime `.sec-list strong` landed at 3.59:1 and 4.04:1 against the gradient behind it, under the
   4.5:1 floor. The same strings in white measure 4.54:1 and 5.11:1.
   Short CTA bands never exposed this because their content sits over the dark end of the ramp.
   Consequence, deliberate: the lime inline links in the contact, sponsor and about CTA bands turn
   white too. That matches the home's CTA, which has always been white type plus a lime button. */
.itg-cta{--accent-text:var(--itg-white);}

/* ── CTA FORM ── the compact inline signup on the CTA band: field + button as one unit, gap 0 so
   they read as a single control. Centred at a 480px measure because a full-width field on a 1280px
   band reads as a search bar, not a signup. Wraps below 480 so the button drops under the field
   instead of squeezing it. (2026-08-17, promoted from the home's inline styles.) */
.cta-form{display:flex;gap:0;flex-wrap:wrap;justify-content:center;max-width:480px;margin:0 auto;}
.cta-form .input{flex:1;min-width:240px;}

/* ── CTA FORM STATUS ── the line subscribe-form.js writes under the field after a submit.
   Created by JS, not baked into the 202 pages, so it costs nothing until it is used.
   flex-basis:100% forces its own row inside the flex container instead of squeezing in
   beside the field. Reads --fg-muted / --accent-text / --eyebrow so it inverts with the
   band like every other module (the context rule at the top of tokens.css) — the CTA band
   is dark today but contact and sponsor put forms on light grounds.
   The error colour is the one literal here: the palette has no error token, and inventing
   one for a single status line would be a bigger change than it earns. (2026-08-19) */
.cta-form-status{flex-basis:100%;margin:14px 0 0;text-align:center;
  font-family:var(--font);font-size:var(--t-ui);line-height:1.5;color:var(--fg-muted);}
.cta-form-status:empty{margin:0;}
.cta-form-status.is-pending{color:var(--fg-muted);}
.cta-form-status.is-err{color:#ff6b6b;}

/* ── FORM DONE ── the confirmation panel that REPLACES a submitted form (hubspot-forms.js).
   Not a line under the field: the form and the section's pitch are both removed and this
   takes their place, so there is no ambiguity about whether the submit landed. Sized to hold
   the band on its own - these sections were built around a form and collapse awkwardly if the
   replacement is only one line tall. (2026-08-19, Nico asked for a real confirmation.) */
.form-done{max-width:560px;margin:0 auto;text-align:center;padding:8px 0 4px;
  animation:form-done-in .32s cubic-bezier(.2,.7,.3,1) both;}

/* --accent, not --accent-text: the tick is a MARK, not type, so it keeps the lime that the
   CTA band deliberately strips from text (see .itg-cta at the top of this file). */
.form-done-tick{width:64px;height:64px;margin:0 auto 22px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:32px;line-height:1;color:var(--accent);
  border:2px solid var(--accent);
  box-shadow:0 0 30px rgba(150,255,0,.28);}

.form-done-t{font-family:var(--font);font-weight:var(--w-display,900);
  font-size:clamp(26px,3.4vw,38px);line-height:1.06;letter-spacing:.01em;
  text-transform:uppercase;color:var(--fg);margin:0 0 14px;text-wrap:balance;}

.form-done-d{font-family:var(--font);font-weight:var(--w-body,400);font-size:var(--t-ui);
  line-height:1.6;color:var(--fg-muted);margin:0;text-wrap:pretty;}

@keyframes form-done-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.form-done{animation:none;}}

/* List labels on the gradient are CYAN ITALIC — the eyebrow voice, not the accent voice
   (Nico, 2026-08-14). Reads --eyebrow rather than a literal, so it is the same cyan the eyebrows
   above them use and it would follow the token if the palette ever moved. */
.itg-cta .sec-list strong{color:var(--eyebrow);font-style:italic;}

/* ══ ABOUT THE SHOW + HOSTS ══ copy left, host portraits right (2026-08-13, Nico) ════ */
    .ab-row{display:flex;align-items:flex-start;justify-content:space-between;gap:48px 72px;flex-wrap:wrap;}

.ab-copy{flex:1 1 560px;max-width:660px;}

.ab-copy p{margin:0 0 32px;}

.ab-hosts{display:flex;flex:0 0 auto;gap:24px;}

/* on dark  */
    /* Removed: the ghost button's resting colour now comes from --fg, which .itg-light already
       redefines. Keeping a per-context override here is exactly the duplication tokens exist to
       kill — and it was the reason the light button also inherited a glow. (2026-08-14) */

/* hover on light: fill + border only. --glow is `none` in the light context because a glow
   simulates emitted light and white has nothing to illuminate; the spread just reads as a
   blurry halo. (Nico, 2026-08-14) */
.itg-light .btn-ghost:hover{border-color:var(--accent);box-shadow:var(--glow);}

/* the wipe already reads --accent, which is #8ed800 in this context */

/* SELF-CENTERING (2026-08-17). Every section shell in this system is a max-width block sitting in a
   full-bleed band, so the auto margin is part of the module, not something each page should have to
   remember. Until now index/books/episodes each carried `section{margin:0 auto}` in their private
   reset and episode-178.html did not — so its CTA band rendered hard-left with 605px of dead space
   on the right at 1885px wide. Invisible at exactly 1280px, which is why it survived a full
   verification pass: at the viewport that equals --measure-grid an uncentred 1280px block looks
   identical to a centred one. The pages that already declare it are now redundant, not wrong. */
.sec,.sec--emphasis,.sec--tight{margin-inline:auto;}

.sec{padding:var(--sec-pad) var(--sec-pad-x);}

/* a colour boundary is a hard visual edge, so content needs MORE clearance from it than
       from a neighbouring section that shares the same ground */
    .sec--zone-start{padding-top:var(--zone-pad);}

.sec--zone-end{padding-bottom:var(--zone-pad);}

.sec--tight{padding:var(--sec-tight) var(--sec-pad-x);}

.sec--group-top{padding-bottom:var(--sec-group);}

.sec--group-bottom{padding-top:var(--sec-group);}

.sec--emphasis{padding:var(--zone-pad) var(--sec-pad-x);}

/* ══ VIDEO ROW ══ copy in column 1, player spanning columns 2-3. Deliberately the SAME
       3-col / 24px grid as the Latest-episodes cards below, so the player's left edge lands on
       the second card's edge. (2026-08-13, Nico) */
    .vid-row{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;align-items:start;}

.vid-copy{grid-column:1;}

.vid-frame{grid-column:2 / span 2;}

/* ══ SPONSOR section ══ (2026-08-13, Nico) ═══════════════════════════════════════════
       Copy left / CTA right, matching the intermediate home. Sponsors sit below, left-aligned
       to the same edge so the section holds a single alignment axis. */
    /* margin-bottom removed 2026-08-14: it separated this row from the sponsors strip, which
       now lives on the white band. With nothing below it, 64px was dangling at the end of
       the section and inflating the seam to About2 from 192 to 264. */
    .sp-top{display:flex;align-items:center;justify-content:space-between;gap:40px 56px;flex-wrap:wrap;}

.sp-top .btn-ghost{flex:0 0 auto;}

/* ══ HOST ROW ══ circular portrait left, full bio right. (2026-08-14, Nico) ═══════════
   Ported from the intermediate site's `.host-card` (grid 240px / rest, with a 240px circular
   photo) for about.html. It replaces the `.ab-row` + `.ab-host` pairing on that page: those are
   the HOME's compact 212px host cards with the copy on the left, and reusing them there made the
   about page read as a different site than the one we are recreating.
   `--t-small` body, not `--t-body`: these are long bios, and 20px over 822px is too loose a
   measure. Weight comes from --w-body-ctx so the row survives a move onto the white band.
   Reusable by the per-guest pages in MIGRATION-PLAN.md §1. */
/* One shape, two measures. `.book-row` (books.html, 2026-08-14) is the same media-left/copy-right
   grid as `.host-row`, only wider on the media side because a book cover is a 2:3 portrait and a
   host badge is not. Sharing the selector rather than copying the rule is the whole point of the
   2026-08-14 audit; --media-w is the only thing that differs. */
    .host-row,.book-row{display:grid;grid-template-columns:var(--media-w) 1fr;gap:56px;align-items:start;}

.host-row{--media-w:240px;}

.book-row{--media-w:280px;}

.host-row + .host-row{margin-top:72px;}

/* ══ EPISODE CARD ══ the catalog unit: cover, date, title, guest + company. ══════════════════
   PROMOTED TO THE SYSTEM 2026-08-17 (Nico picked the home's treatment as canon for the whole
   catalog). It previously existed TWICE and was a module neither time: as inline styles inside
   index.html's dc markup, and as a private <style> block in episodes.html that had drifted into a
   different design altogether — 1px cyan border, cyan glow on hover, sitting on a dark band. The
   drift is the argument for a module. This is now the one definition.

   NAMESPACE — `epcard-`, not `ep-`, and that matters. The first version of this module used `.ep-`
   and silently collided with episode-178.html, which had been using `.ep-title` for its 48px HERO
   heading and `.ep-body` for its two-column article grid since before this module existed. Because
   blocks.css loads before a page's own <style>, the episode page's hero title inherited this card
   title's `-webkit-line-clamp:3`. Renamed 2026-08-17 the same day it was introduced. `ep-` belongs
   to the episode PAGE, which is about to be batched across 178 files; the card gets `epcard-`.

   THE CARD IS A DARK ISLAND ON A LIGHT BAND, which is the whole trick here. It must be marked
   `class="epcard ctx-dark"`: the white band sets --fg to near-black for its subtree, so without
   re-asserting the dark context the card's own title would go dark-on-dark. With ctx-dark it reads
   ONLY context tokens (--surface, --fg, --eyebrow, --accent) and therefore renders correctly on the
   white band, on the ink ground, and on any band added later, from a single rule. That is exactly
   the CONTEXT RULE in tokens.css, and it is why this module hardcodes no colour where the home's
   inline version hardcoded #fff, #36ecff and #96ff00.
   Note it deliberately uses NO <p>: `.itg-light p` carries `color: ... !important`, which would
   punch through the card's context. Headings and divs only.
   No border on purpose (the home's call): the surface contrast carries the edge and the hover
   shadow carries the lift, so a border would be a third redundant signal. */
/* minmax(0,1fr), NOT 1fr. Plain `1fr` means minmax(AUTO,1fr), so any unbreakable child can push its
   column wider than its siblings — and `.cmeta` is unbreakable by design (white-space:nowrap keeps
   the hover wipe overlay aligned with its text). Measured on the first 21: one single episode,
   "Brett Fulmer · Newport Beach Insurance Center L…", needed 360px in a 354px column and widened
   the third column from 373px to 390px across all seven rows. minmax(0,1fr) pins the columns equal
   and `.epcard-meta{overflow:hidden}` below contains the outlier. (2026-08-17) */
/* EVERY CARD IS THE SAME SIZE, always, whatever the title length (Nico, 2026-08-17). Three things
   are needed for that and all three are here, because any one alone leaves the grid ragged:
     grid-auto-rows:1fr   equalises rows across the WHOLE grid, not just within a row. Measured on
                          the full 178: heights came in ELEVEN distinct values before this.
     align-items:stretch  (the default, so `start` had to GO — it was sizing each card to its own
                          content, which is what made the 1-line-title cards visibly shorter)
     the img aspect-ratio further down, which reserves the cover's box BEFORE the lazy image
                          loads. Without it a card is short until its image arrives.
   Cost of grid-auto-rows:1fr is that the tallest card sets the height for all, which is exactly why
   .epcard-title is clamped below rather than left unbounded. */
.epcard-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;
         grid-auto-rows:1fr;align-items:stretch;}

/* flex column so .epcard-body can absorb the slack a uniform row height creates, which is what lets the
   guest + company line sit on the card's bottom edge instead of floating wherever the title ends */
.epcard{display:flex;flex-direction:column;text-decoration:none;color:var(--fg);border:0;
         border-radius:var(--r-card);background:var(--surface);}
.epcard:hover{transform:translateY(-3px);}

/* the teal-to-ink ramp behind the artwork: it shows while the image lazy-loads and fills the
   letterboxing on any cover whose ratio is not 553/400 */
.epcard-cover{position:relative;overflow:hidden;line-height:0;
          border-radius:var(--r-card) var(--r-card) 0 0;
          background:linear-gradient(135deg,#00a8ba 0%,#00374a 55%,var(--itg-ink) 100%);}
/* aspect-ratio, not height:auto: every episode plate is 553x400, and declaring it reserves the box
   before the lazy image arrives. Without it the card is short until load, so the row heights
   settle late and the grid visibly reflows as you scroll. */
.epcard-cover img{width:100%;height:auto;display:block;aspect-ratio:553/400;object-fit:cover;}

/* episodes 1-69 were never published as WP posts, so no artwork exists for them (see the project
   CLAUDE.md). They get the branded logo plate instead of a broken image. */
.epcard-cover--empty{aspect-ratio:553/400;display:flex;flex-direction:column;align-items:center;
                 justify-content:center;gap:12px;line-height:normal;}
.epcard-cover--empty img{height:38px;width:auto;opacity:.9;}
.epcard-cover--empty span{font-weight:var(--w-strong);font-size:var(--t-meta);letter-spacing:.16em;
                      text-transform:uppercase;color:var(--fg-muted);}

.epcard-body{padding:16px 18px 20px;display:flex;flex-direction:column;flex:1;}
/* 12px, one step under --t-meta: the only literal in this module. It is the date micro-label and
   13px read as a second title next to the 20px name. Promote to a token if a second consumer
   appears. */
.epcard-date{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
         color:var(--eyebrow);margin-bottom:8px;}
/* Clamped to 3 lines. Measured over all 178 titles at this column width: 69 run 1 line, 67 run 2,
   38 run 3 and 4 run FOUR. Leaving it unbounded would make the uniform row height obey those 4
   outliers and hand three lines of dead space to the 69 one-liners. Clamping at 3 costs those 4
   titles an ellipsis and nothing else; clamping at 2 would have cost 42 of them, which is why it is
   3 and not 2. The 4 outliers are also the ones whose titles END in "With <guest> from <company>",
   already shown verbatim on the .epcard-meta line below, so the clamped tail is redundant anyway. The
   real fix is cleaning those titles in episodes-data.js. (2026-08-17) */
.epcard-title{font-family:var(--font);font-weight:600;font-size:var(--t-body);line-height:1.14;
          letter-spacing:var(--track-tight);color:var(--fg);margin:0 0 10px;text-wrap:balance;
          display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;}
/* overflow lives HERE, on the flex container, not on .cmeta: clipping .cmeta itself would also clip
   its ::after wipe overlay and risk desyncing the animation. This way the rare over-long
   guest + company string clips at the card edge and the wipe is untouched. */
/* margin-top:auto pins this to the card's bottom edge, so with uniform row heights the guest lines
   align across a whole row instead of each one sitting wherever its title happened to end. */
.epcard-meta{display:flex;align-items:center;font-size:var(--t-ui);overflow:hidden;margin-top:auto;}

/* the catalog's paging controls, centred under the grid */
.epcard-count{font-family:var(--font);font-size:var(--t-meta);letter-spacing:var(--track-label);
          text-transform:uppercase;color:var(--fg-muted);margin-top:20px;}
.epcard-more{display:flex;justify-content:center;margin-top:56px;}
.epcard-more:empty{display:none;}

@media (max-width:980px){.epcard-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:620px){.epcard-grid{grid-template-columns:1fr;}}

/* ── BOOK COVER ── (2026-08-14)
   2:3 box, the native ratio of all three flat covers (720x1080, 1200x1840, 334x500), so none of
   them crops meaningfully. --r-card, not square like the source: every image object on this site
   is a rounded badge (see .ab-host, .host-avatar).
   `--fit` (object-fit:contain, square corners) was DELETED 2026-08-17: it existed solely for the
   512x512 3D mockup that used to stand in for The End of Insurance, and its own comment said to
   delete it the day a real flat cover for that title existed. That day came — Nico asked for all
   three books to read as flat cover art, so ONE rule now covers all three and there is no
   per-book exception left. */
    .book-cover{width:100%;aspect-ratio:2/3;object-fit:cover;object-position:center;display:block;
            border-radius:var(--r-card);}

/* ── PULL QUOTE ── an author's line lifted out of the copy. Accent rule on the leading edge, the
   same square-marker language as .deflist / .sec-list, and --accent-text so it survives a move
   between bands. */
    .pullquote{margin:0 0 20px;padding-left:22px;border-left:3px solid var(--accent-text);
           font-family:var(--font);font-weight:var(--w-body-ctx);font-style:italic;
           font-size:var(--t-body);line-height:1.5;color:var(--fg);}

/* Rounded-rect badge, not a circle (2026-08-14, Nico): the same object the home's `.ab-host`
   cards are — --r-badge, the card ground, a hairline edge. The intermediate site crops these to
   circles; matching the home matters more, so the two hosts read as the same component in both
   places.
   240x272 is the home card's 212x240 ratio (0.883) scaled up, which is also the native ratio of
   the ep170 host stills (424x480). Chosen so the images crop by nothing at all. If a future
   portrait set ships at another ratio, change this pair together, not one side. */
    .host-avatar{width:240px;height:272px;border-radius:var(--r-badge);object-fit:cover;
             object-position:center top;display:block;
             background:var(--itg-surface);border:1px solid var(--line);}

.host-row p,.book-row p{font-family:var(--font);font-weight:var(--w-body-ctx);font-size:var(--t-small);
            line-height:1.6;color:var(--fg);margin:0 0 20px;}

.host-row p:last-child,.book-row p:last-child{margin-bottom:0;}

/* the two-button row every book block closes on */
.btn-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;margin:28px 0 20px;}

/* Since 2026-08-17 the button row is the LAST thing in a book block (Nico moved the meta line above
   it), so its trailing 20px had nothing left to separate it from and just padded the block out.
   Same :last-child logic already used by `.host-row p,.book-row p`. */
.btn-row:last-child{margin-bottom:0;}

/* ── BOOK META ── the publication line under a book's button row: press, ISBNs, editions, status.
   (2026-08-17, Nico asked for these to read blue + italic.)
   It was .fcard-d, which was wrong twice over: .fcard-d is the FEATURE-CARD description, shared by
   the sponsor ad formats, the about press cards and the form notes, so restyling it would have
   repainted 20 unrelated places; and at --fg-muted it read as body copy rather than as the
   bibliographic footnote it is.
   Italic + --accent-text is NOT a new voice: it is the same treatment as .ab-host .h-role, the
   host's role line, so a secondary attribution line reads the same way everywhere on the site.
   --accent-text, never a literal blue: that token is ITG Blue on white and lime on dark, so this
   line survives a move onto a dark band. On the white band it lands at 6.37:1, past AA.
   This rule declares ONLY what it actually changes. Size and weight are deliberately absent: the
   line keeps the 17px/600 it already had from `.host-row p,.book-row p` and `.itg-light p`, because
   Nico asked for blue and italic, not a new size.
   The scoping and the !important are both load-bearing, not sloppiness: `.itg-light p` sets
   `color: ... !important`, which only another !important can beat, and `.book-row p` at (0,1,1)
   outranks a bare `.book-meta` at (0,1,0). Hence `.book-row .book-meta`. The real cleanup is to
   drop the !important from `.itg-light p` and let the token cascade work, but that rule is load-
   bearing on five other pages, so it is left alone here. */
.book-row .book-meta{font-style:italic;color:var(--accent-text) !important;margin:0;}

/* ── FORM, single column ── (2026-08-14, Nico)
   sponsor.html and contact.html run their forms as a `.grid-2` because those forms are wide and
   full-bleed. subscribe.html's sits in one half of a two-column section, where a second field
   column would be cramped, so it stacks. One property, but named: this is now the third form on
   the site and the shape will repeat on the footer newsletter and the episode pages. */
    .form-col{display:grid;gap:22px;}

/* ══ SPLIT SECTION ══ two equal columns with real air between them. (2026-08-14, Nico) ══
   `.grid-2` is a CARD grid: a 24px gap is right between two cards and far too tight between a
   column of prose and a form, which need to read as separate halves. Collapses at 900px, not
   .grid-2's 560px, because two half-width forms stop working long before phone width. */
    .split-2{display:grid;grid-template-columns:1fr 1fr;gap:72px;align-items:start;}

@media (max-width:900px){
  .split-2{grid-template-columns:1fr;gap:56px;}
}

/* ── the left column is a stack: portrait, then the host's marks (2026-08-14, Nico) ──
   These were text pills in the bio column. As icon marks under the photo they read as part of the
   person rather than as another tag row, which is also how the footer treats the show's socials. */
    .host-media{display:flex;flex-direction:column;align-items:flex-start;gap:18px;}

.host-links{display:flex;align-items:center;gap:16px;}

.host-ico{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;
          text-decoration:none;}

/* Masked, not <img>: the colour is then exact at rest and on hover. The mask plumbing lives once,
   in primitives.css (`.plt-icon,.host-ico-i,.ft-soc-i`); only the box and the colour are here.
   NOTE the `../` on the mask urls below — they resolve against THIS stylesheet in css/, not
   against the page. */
    .host-ico-i{width:26px;height:26px;background-color:var(--fg-muted);
            transition:background-color var(--dur) var(--ease);}

/* Hover goes to --eyebrow (cyan on dark, ITG Blue on white) and carries NO glow: the footer's
   marks add a cyan drop-shadow, but a filter cannot read --glow, so a hardcoded one would follow
   the icons onto a light band where the system forbids glows. Colour alone does the work. */
    .host-ico:hover .host-ico-i{background-color:var(--eyebrow);}

.host-ico--x   .host-ico-i{-webkit-mask-image:url('../assets/social/x-twitter-isologo.svg');mask-image:url('../assets/social/x-twitter-isologo.svg');}

.host-ico--li  .host-ico-i{-webkit-mask-image:url('../assets/social/linkedin-isologo.svg');mask-image:url('../assets/social/linkedin-isologo.svg');}

.host-ico--web .host-ico-i{-webkit-mask-image:url('../assets/social/globe-isologo.svg');mask-image:url('../assets/social/globe-isologo.svg');}

@media (max-width:820px){
  .host-row{grid-template-columns:1fr;gap:28px;}
}

/* ══ PLATFORM ROW ══ the listen-on strip's wrapper. (2026-08-14, audit) ═══════════════
   The same five .plt-links appear on the home and on about.html, but each page wrote the row's
   layout inline and the two had drifted (the home also carried max-width/margin, which is the
   section container's job, not the row's). subscribe.html and every episode page will want this
   row too. 64px gap: the marks are optically different widths, so a wide gap keeps the labels
   from crowding. */
    .plt-row{display:flex;align-items:flex-start;gap:64px;flex-wrap:wrap;justify-content:center;}

/* ── GRIDS ── one gap token, used by every card layout on the site. */
.grid-2{display:grid;grid-template-columns:repeat(2,1fr);gap:24px;}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;}
@media (max-width:900px){
  .grid-3,.grid-4{grid-template-columns:repeat(2,1fr);}
  .deflist--2col{grid-template-columns:1fr;}
}
@media (max-width:560px){
  .grid-2,.grid-3,.grid-4{grid-template-columns:1fr;}
}

/* ── SECTION HEADER ── eyebrow + title + optional copy. The shape every section repeats. */
.sec-head{margin-bottom:56px;}
.sec-head--center{text-align:center;}
.sec-head--center .sec-copy{margin-left:auto;margin-right:auto;}
.sec-title{font-family:var(--font);font-weight:var(--w-display);font-size:var(--t-h2);
           line-height:var(--lh-h2);letter-spacing:var(--track-tight);text-transform:uppercase;
           color:var(--fg);margin:0 0 20px;text-wrap:balance;}
.sec-copy{font-family:var(--font);font-weight:var(--w-body-ctx);font-size:var(--t-body);
          line-height:var(--lh-body);color:var(--fg);max-width:680px;margin:0;}

/* ── WIDE measure for .sec-copy ── (2026-08-17, Nico)
   680px at 20px type is ~68 characters, the optimal reading measure, and it is right for copy that
   sits in a column next to something else. It is WRONG for a long CENTRED paragraph: the same words
   stack into a tall narrow slab in the middle of a 1280px band, which is what the books.html
   closing note looked like (95 words, 8 lines).
   900px is ~90 characters: wider than optimal but still inside the readable range, and it lets a
   centred block breathe. Deliberately NOT --measure-prose (1080px), which at this size would run
   ~108 characters per line and read as a wall.
   Use on centred .sec-head--center copy only. The real fix for a slab is usually fewer words. */
.sec-copy--wide{max-width:900px;}

/* One step below .sec-title, for a heading that lives INSIDE a section rather than opening it —
   the host names on about.html, and the per-guest and per-topic headings to come. Same voice as
   .sec-title (Titillium 900, uppercase, tight tracking) at --t-h3, so a name reads as a title and
   not as a bold label, without competing with the 46px heading above it. (2026-08-14, Nico) */
.sec-title--h3{font-size:var(--t-h3);line-height:1.1;}

/* .sec-sub (a 26px deck between title and body) was introduced and then REMOVED on 2026-08-14.
   It created a third size for the line after a section title — 20px on the home, 26px on
   sponsor — so the two pages read differently. The 46px -> 20px step needs no intermediate:
   the copy reads fine at body size, and one less level is one less thing to keep consistent.
   If a deck is ever genuinely needed, add it here and apply it EVERYWHERE, not per page. */

/* ── PAGE BEHAVIOUR + ANCHOR OFFSET ──────────────────────────────────────────────────────────
   In-page links scroll smoothly, and any anchor target clears the sticky navbar. Without
   scroll-margin-top the target lands UNDER the nav and the jump looks broken. One variable so
   the offset cannot drift from the real nav height. (2026-08-14) */
html{scroll-behavior:smooth;}
:root{--nav-h:89px;}
[id]{scroll-margin-top:calc(var(--nav-h) + 24px);}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto;} }

/* ── SPLIT SECTION HEADER ── title + copy on the left, one action on the right.
   Third use of this shape on the site (the home's sponsor teaser and this), so it becomes a
   module rather than another one-off. Vertically centred, unlike .vid-row / .ab-row which are
   content+media rows and align to the top. (2026-08-14, Nico) */
.sec-head--split{display:flex;align-items:center;justify-content:space-between;gap:32px 56px;flex-wrap:wrap;}
.sec-head--split .sec-head-text{flex:1 1 560px;}
.sec-head--split .sec-head-text > :last-child{margin-bottom:0;}
.sec-head--split > .btn-ghost,.sec-head--split > a{flex:0 0 auto;}

/* ============================================================================================
   HERO VIDEO - James talking on the right of the home hero, dissolving into the page.
   (2026-08-18, Nico: "ponelo en el hero del home a la derecha con degradado para que funda a
   transparente ... como tiene la pagina vieja".)

   HOW IT DISSOLVES. Two separate mechanisms, on purpose:
     mask-image on the frame  fades the video's own ALPHA to nothing toward the left, so the
                              footage really ends rather than sitting on a painted panel. This is
                              what makes it read as "fundido a transparente" over the grid
                              background instead of a rectangle with a gradient stuck on it.
     .hero-vid__scrim         a painted top/bottom fade plus a left darkening pass, which is what
                              keeps the H1 legible where the two overlap. A mask cannot do this
                              job: masking the top and bottom as well would need mask-composite,
                              which Safari still spells differently.
   Overlap with the headline is intended - the old site does exactly that.

   The poster is the CSS background of the frame, not only the video's poster attribute, so the
   picture is present before playback and also for anyone who never gets playback: under 900px the
   video element is dropped (a 55% wide panel is pointless on a phone) and with
   prefers-reduced-motion the still is all that shows. No JS is involved in any of that.

   object-position 0% 30% with a 44% panel: measured, not guessed. Cover scales the clip to the
   panel's HEIGHT, so a wide panel leaves only ~213px of horizontal slack and object-position runs
   out of travel long before the subject clears the headline. Narrowing the panel does both jobs at
   once: it starts further right on screen and it gives the crop more slack. Rendered as three
   candidates and compared against the H1's measured right edge (1253px at a 1600px viewport);
   this is the one where James sits fully clear of the title.
   ============================================================================================ */
.hero-vid{
  position:absolute;top:0;bottom:0;
  width:min(44%,760px);
  overflow:hidden;pointer-events:none;z-index:0;
  /* MIRRORED AND MOVED LEFT (2026-08-18, Nico: "lo quiero espejado ... y que este del lado
     izquierdo"). The flip is applied to the FRAME, not to the video, on purpose: one transform
     mirrors the footage, the poster, the tint ramp and both masks together, so a fade defined
     toward the frame's left keeps landing on the screen's inner edge with no gradient rewritten. */
  /* 20% larger, growing DOWNWARD (Nico: "con el pivot en el centro de su video arriba"). The origin
     is top centre, so the top edge stays welded under the navbar and the extra height all goes down,
     where the mask is already fading out. scaleX(-1) has to stay in the same transform: writing it
     separately would replace the mirror instead of combining with it. */
  transform-origin:50% 0;
  /* 90% (Nico). On the FRAME, not on the <video>: the poster sits behind the footage, so fading the
     video alone would reveal the same picture underneath and change nothing. */
  opacity:.90;
  /* VERTICAL fade, in ALPHA (2026-08-18, Nico: "que la parte de abajo tambien este soft fundido a
     transparente"). This replaces a gradient that painted opaque --itg-ink at the top and bottom.
     Painting ink is not fading to transparent: the .grid-bg lines run behind the hero, so an
     ink-filled bottom HID the grid and the panel ended in a hard horizontal edge exactly where the
     grid reappeared - the seam in Nico's screenshot. A mask removes the pixels instead, so the grid
     shows straight through and the footage dissolves into it.
     Two axes without mask-composite: this element carries the vertical ramp and .hero-vid__inner
     carries the horizontal one. Masks on nested elements compose by themselves, so nothing depends
     on mask-composite / -webkit-mask-composite still disagreeing between engines. */
  -webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,#000 14%,#000 62%,rgba(0,0,0,.35) 88%,rgba(0,0,0,0) 100%);
          mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,#000 14%,#000 62%,rgba(0,0,0,.35) 88%,rgba(0,0,0,0) 100%);
}
/* the horizontal dissolve, plus the poster - which must live HERE so it is masked on both axes too,
   otherwise the still would end in a hard vertical edge wherever the video is not playing */
.hero-vid__inner{
  position:absolute;inset:0;overflow:hidden;
  background:#0a0d12 url("../assets/james-hero-poster.jpg?v=2") 0% 30%/cover no-repeat;
  -webkit-mask-image:linear-gradient(to right,rgba(0,0,0,0) 0%,rgba(0,0,0,.10) 16%,rgba(0,0,0,.45) 34%,rgba(0,0,0,.82) 58%,#000 82%);
          mask-image:linear-gradient(to right,rgba(0,0,0,0) 0%,rgba(0,0,0,.10) 16%,rgba(0,0,0,.45) 34%,rgba(0,0,0,.82) 58%,#000 82%);
}
/* object-position 0% 30% with a 44% panel: measured, not guessed. Cover scales the clip to the
   panel's HEIGHT, so a wide panel leaves only ~213px of horizontal slack and object-position runs
   out of travel long before the subject clears the headline. Narrowing the panel does both jobs at
   once: it starts further from the centre and it gives the crop more slack. Rendered as three
   candidates and compared against the H1's measured edge at a 1600px viewport. */
.hero-vid__el{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:0% 30%;display:block;
  filter:saturate(.42) contrast(1.07) brightness(.92);
}
/* ITG GREEN TINT (2026-08-18, Nico: "que tenga un tinte verde ITG").
   mix-blend-mode:color keeps the footage's LUMINANCE and takes only hue and saturation from this
   layer, so James stays readable as a person instead of turning into a flat green silhouette - a
   plain rgba overlay would wash the midtones out instead of recolouring them.
   The ramp runs cyan to lime across the frame, the same two-accent wash the old site used, and the
   video's own saturation is pulled down to .42 above so this layer is what the eye reads as colour. */
.hero-vid__tint{
  position:absolute;inset:0;
  background:linear-gradient(112deg,
    rgba(54,236,255,.85) 0%,
    rgba(88,247,160,.92) 38%,
    rgba(150,255,0,1) 72%,
    rgba(150,255,0,1) 100%);
  mix-blend-mode:color;
  opacity:.66;
}
/* only the INNER-edge darkening survives from the old scrim: it sits inside the masked area, so it
   deepens the footage under the headline without painting over the grid */
.hero-vid__scrim{
  position:absolute;inset:0;
  background:linear-gradient(to right,rgba(4,6,10,.70) 0%,rgba(4,6,10,.26) 40%,rgba(4,6,10,0) 72%);
}
/* SIDE. James sits on the left, mirrored in CSS: the inner mask fades toward the frame's own left
   edge, so mirroring the frame lands that fade on the screen's RIGHT - the inner edge - from a single
   gradient definition. The panel is pulled 60px past the viewport edge by the 1.2 scale, so its outer
   seam falls off screen.
   A matching right-hand panel with Rob existed here (2026-08-18) and was removed the same day at
   Nico's request: "eliminma el video de rob no lo utilizaremos". Its assets went with it. */
.hero-vid--left{
  left:10px;
  transform:scaleX(-1) scale(1.2);
}

/* the hero content must sit above the footage */
.hero-copy{position:relative;z-index:2;}

@media (max-width:900px){
  .hero-vid{display:none;}
}
@media (prefers-reduced-motion:reduce){
  .hero-vid__el{display:none;}
}

/* ============================================================================================
   ASK PAGE MODULES — ask.html's own sections. The floating widget's chrome (.itg-ask-*, .itg-chip
   inside the panel) lives in ask-widget.css; these are for the STATIC page around it: the sample
   questions and the "how it works" steps. Named .ask-suggest / .itg-step rather than reusing the
   widget's .itg-chip, since these are page cards on whichever band the section sits on (context-
   aware via --surface/--line/--accent-text), not fixed dark UI.
   ============================================================================================ */
.ask-suggest-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;}
.ask-suggest{
  text-align:left;padding:18px 20px;cursor:pointer;
  font-family:var(--font);font-weight:700;font-size:var(--t-ui);line-height:1.4;color:var(--fg);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);
  transition:transform var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.ask-suggest::before{content:'✨ ';}
.ask-suggest:hover{transform:translateY(-2px);border-color:var(--accent-text);}

/* ── numbered steps ── same visual language as the episode page's .takeaway/.ta-num (a ringed
   circle badge), reimplemented here rather than shared: episode.css loads only on episode pages,
   and this module belongs to any top-level page that walks through a short process. */
.itg-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:28px;}
.itg-step-num{
  display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border-radius:50%;
  background:color-mix(in srgb, var(--accent-text) 9%, transparent);
  border:2px solid var(--accent-text);
  font-family:var(--font);font-weight:var(--w-strong);font-size:var(--t-body);color:var(--accent-text);
  margin-bottom:14px;
}
.itg-step h3{
  font-family:var(--font);font-weight:var(--w-strong);font-size:var(--t-term);color:var(--fg);
  margin:0 0 8px;
}
.itg-step p{
  font-family:var(--font);font-weight:var(--w-body-ctx);font-size:var(--t-small);line-height:1.6;
  color:var(--fg-muted);margin:0;
}
