/* ==========================================================================
   Ambition & Life — site stylesheet
   Built from the Ambition & Life design system (Karis Dorrigan).
   Mobile-first. Breakpoints: 390 base / 768 tablet / 1120 desktop.

   Everything is driven by the tokens in section 2. Never write a raw hex
   in page markup; add a token here instead.
   ========================================================================== */

/* ==========================================================================
   1. FONTS
   Self-hosted. Montserrat Medium stands in for Regular until the Regular
   file is supplied (weight 400 currently maps to the Medium file).
   ========================================================================== */

@font-face {
  font-family: "Recoleta";
  src: url("../fonts/Recoleta-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-Medium.ttf") format("truetype");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-Bold.otf") format("opentype");
  font-weight: 600 700;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   2. TOKENS
   ========================================================================== */

:root {
  /* ---- Core brand palette (exact spec values, unchanged) ---- */
  --kd-navy:         #203845;
  --kd-royal-blue:   #2461ff;
  --kd-lavender:     #b9b5ff;
  --kd-chalked-blue: #dbe4f0;
  --kd-tan:          #e7dbc3;
  --kd-warm-gray:    #f7f6f4;
  --kd-white:        #ffffff;

  /* ---- Derived interaction values (blends of the six brand colours) ---- */
  --kd-royal-700: #235ae1;   /* hover   — royal 84% + navy */
  --kd-royal-800: #2352b1;   /* press   — royal 66% + navy */
  --kd-royal-100: #e9effe;   /* tint surface */

  --kd-navy-700:  #3f545f;   /* secondary ink */
  --kd-navy-300:  #849299;   /* DECORATIVE ONLY — see note below */
  --kd-navy-100:  #ccd1d4;   /* hairline */

  --kd-lavender-200: #dedcff;
  --kd-tan-200:      #f3ecdf;

  /* ---- Accessibility-corrected ink -------------------------------------
     AA CORRECTION. The design files use --kd-navy-300 (#849299) for all
     overline, caption, legal and footer text. Measured against the brand
     surfaces it scores 3.20 on white, 2.97 on warm gray, 2.50 on chalked
     blue and 2.34 on tan — all below the 4.5:1 AA floor for text at these
     sizes (9–12px). --text-muted is navy at 79% and scores 6.37 / 5.90 /
     4.97 / 4.65 on the same four surfaces.

     Rule: --text-muted for anything a person reads.
           --kd-navy-300 for hairlines, pipes and decorative marks only.
     See README "Accessibility deviations" before changing this.
     --------------------------------------------------------------------- */
  --text-muted: #4f626c;

  /* Royal blue on the soft surfaces. #2461ff scores 3.87 on chalked blue
     and 3.62 on tan — fine for a 3:1 decorative mark, short of AA for the
     small bold overlines that sit on those grounds. This darker cut scores
     4.89 and 4.58. Plain --kd-royal-blue is retained for white and warm
     gray grounds (4.97 / 4.60) and for button fills. */
  --accent-on-soft: #2357d0;

  /* ---- Semantic aliases ---- */
  --surface-page:   var(--kd-warm-gray);
  --surface-card:   var(--kd-white);
  --surface-soft:   var(--kd-chalked-blue);
  --surface-warm:   var(--kd-tan);
  --surface-ink:    var(--kd-navy);

  --text-heading:   var(--kd-navy);
  --text-body:      var(--kd-navy);
  --text-on-ink:    var(--kd-warm-gray);
  --text-link:      var(--kd-royal-blue);

  --accent:         var(--kd-royal-blue);
  --accent-hover:   var(--kd-royal-700);
  --accent-press:   var(--kd-royal-800);

  --border-subtle:  var(--kd-navy-100);
  --focus-ring:     var(--kd-royal-blue);

  /* ---- Typography ---- */
  --font-serif: "Recoleta", Georgia, "Times New Roman", serif;
  --font-sans:  "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --font-display: var(--font-serif);
  --font-ui:      var(--font-sans);

  --weight-regular: 400;
  --weight-medium:  500;
  --weight-bold:    700;

  /* Responsive type scale. Overridden at 768 and 1120.

     --t-h1 is the HOME hero size. The spec is explicit that the other pages
     do not match it: "Home hero 60 desktop; Waitlist, Salon and Podcast
     heroes 52-54". --t-h1-page carries that smaller size and is applied by
     .page-hero, so the four inner pages stop borrowing Home's headline.

     --t-h2 is the BASE section heading. The design does not use one size for
     every section: measuring the mockups gives a three-step scale, and
     flattening it to a single value is the main reason the built page reads
     as evenly grey where the design has emphasis. The three steps are held
     in --t-h2-xl / -lg / -sm below and applied with the .h2-xl, .h2-lg and
     .h2-sm classes, so a section's weight is declared in the markup next to
     the heading it belongs to rather than guessed at from a global token. */
  --t-h1:      38px;
  --t-h1-page: 30px;
  --t-h2:      25px;
  --t-h2-xl:   30px;
  --t-h2-lg:   27px;
  --t-h2-sm:   25px;
  --t-h3:      20px;
  --t-lead:    20px;
  --t-body:    15px;
  --t-small:   13px;
  --t-overline: 10px;

  --leading-display: 1.05;
  --leading-heading: 1.2;
  --leading-body:    1.6;
  --leading-tight:   1.3;

  --tracking-display:  -0.01em;
  --tracking-overline:  0.16em;
  --tracking-button:    0.08em;

  /* ---- Spacing (8px rhythm) ---- */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 24px;  --space-6: 32px;  --space-7: 48px;  --space-8: 64px;
  --space-9: 96px;

  /* Section rhythm and gutter — grow at each breakpoint.

     --section-y is the standard band. --hero-y is smaller, because in the
     mockups every page hero sits tighter than the sections under it: the
     headline is already doing the work of opening the page and does not need
     the same run-up. Measured off the artboards it is 26 / 48 / 72 against a
     standard band of 32 / 52 / 80. Running one value for both, which is what
     the build did, pushed every hero down the page and cost the whole site
     its sense of pace. */
  --section-y: 32px;
  --hero-y:    26px;
  --gutter:    20px;
  --measure:   68ch;      /* max text measure */

  /* The outer width of .wrap, INCLUDING its two gutters.
     Worth being pedantic about, because everything in this file is border-box.
     The spec's "content capped at 1180px" is the readable column, the part you
     can actually see text and cards sitting in. Setting max-width: 1180px with
     64px of padding gives you 1180 minus 128, so 1052px of column, and every
     page comes out 64px too narrow on each side against the design. So the cap
     is written as the column plus its gutters, and the column lands at 1180. */
  --wrap-max: 100%;

  /* ---- Radii ---- */
  --radius-xs: 6px;   --radius-sm: 10px;  --radius-md: 16px;
  --radius-lg: 24px;  --radius-xl: 32px;  --radius-pill: 999px;

  --blob-0: 42% 58% 63% 37% / 45% 38% 62% 55%;
  --blob-1: 58% 42% 38% 62% / 49% 56% 44% 51%;
  --blob-2: 63% 37% 52% 48% / 38% 55% 45% 62%;

  --border-hairline: 1px;
  --border-regular:  1.5px;
  --border-strong-w: 2px;

  /* ---- Effects ---- */
  --shadow-xs: 0 1px 2px rgba(32, 56, 69, 0.06);
  --shadow-sm: 0 2px 8px rgba(32, 56, 69, 0.08);
  --shadow-md: 0 8px 24px rgba(32, 56, 69, 0.10);
  --shadow-lg: 0 18px 48px rgba(32, 56, 69, 0.14);
  --shadow-accent: 0 10px 28px rgba(36, 97, 255, 0.28);
  --ring: 0 0 0 3px rgba(36, 97, 255, 0.35);

  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast:   140ms;
  --dur-normal: 220ms;
  --dur-slow:   420ms;

  /* Brand gradient — unchanged, retained for decorative use. */
  --gradient-brand: linear-gradient(120deg, #2461ff 0%, #6f7dff 55%, #b9b5ff 100%);

  /* AA CORRECTION. The hero carries white text across its whole width.
     White on the lavender end of --gradient-brand measures 1.93:1. This is
     the same gradient held back before the pale end: every stop scores at
     least 4.6:1 against white. Use this anywhere white text sits on the
     gradient; use --gradient-brand only behind opaque cards or imagery. */
  --gradient-hero:  linear-gradient(120deg, #235ae1 0%, #2461ff 48%, #3068ff 100%);
  --gradient-soft:  linear-gradient(135deg, #dbe4f0 0%, #e8e7ff 100%);
}

/* Tablet. Design frame 834, side padding 40.
   834 is the width the design was DRAWN at. It is not a cap on the content.
   This band runs from 768 all the way to 1119, and a very large number of real
   laptop windows sit at 1000 to 1100. Freezing the column at 834 across that
   whole range left roughly 130px of dead space down each side and made the
   page look cramped and mis-padded on exactly the machines people use most.
   So the column simply fills the window less its gutters here, and only meets
   a hard cap at 1120 where the desktop layer takes over. Text measure is held
   by .prose, not by the wrap, so lines never run too long. */
@media (min-width: 768px) {
  :root {
    --t-h1: 44px;  --t-h1-page: 39px;  --t-h3: 22px;
    --t-h2: 31px;  --t-h2-xl: 36px;    --t-h2-lg: 34px;  --t-h2-sm: 28px;
    --t-lead: 21px; --t-body: 16px; --t-small: 14px; --t-overline: 11px;
    --section-y: 52px;
    --hero-y:    48px;
    --gutter: 40px;
    --wrap-max: 100%;
  }
}

/* Desktop. Frame 1440, content capped 1180, side padding 64.
   1180 is the column, not the box. See the note on --wrap-max above. */
@media (min-width: 1120px) {
  :root {
    --t-h1: 60px;  --t-h1-page: 53px;  --t-h3: 26px;
    --t-h2: 40px;  --t-h2-xl: 48px;    --t-h2-lg: 44px;  --t-h2-sm: 36px;
    --t-lead: 25px; --t-body: 17px; --t-small: 15px; --t-overline: 11px;
    --section-y: 80px;
    --hero-y:    72px;
    --gutter: 64px;
    --wrap-max: calc(1180px + (2 * 64px));
  }
}

/* ==========================================================================
   3. RESET & BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Clears the tallest sticky header (84px on desktop) plus breathing room, so
     an in-page jump never lands behind it. */
  scroll-padding-top: 100px;
}

body {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: var(--weight-medium);
  font-size: var(--t-body);
  line-height: var(--leading-body);
  color: var(--text-body);
  background: var(--surface-page);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  color: inherit;
  letter-spacing: var(--tracking-display);
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); line-height: var(--leading-display); }
h2 { font-size: var(--t-h2); line-height: var(--leading-heading); }
h3 { font-size: var(--t-h3); line-height: var(--leading-tight); }

p  { margin: 0; text-wrap: pretty; }
ul { margin: 0; padding: 0; list-style: none; }

img, picture, svg { display: block; max-width: 100%; }
img { height: auto; }

a { color: var(--text-link); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

strong { font-weight: var(--weight-bold); }
::selection { background: var(--kd-lavender); color: var(--kd-navy); }

/* Visible focus on every interactive thing. Never remove this. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

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

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -100px;
  z-index: 100;
  padding: 12px 20px;
  background: var(--kd-navy);
  color: var(--kd-warm-gray);
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-button);
  transition: top var(--dur-fast) var(--ease-standard);
}
.skip-link:focus { top: var(--space-3); color: var(--kd-warm-gray); text-decoration: none; }

/* ==========================================================================
   4. LAYOUT
   Section backgrounds are always full bleed; only the content column caps.
   ========================================================================== */

.section {
  padding-block: var(--section-y);
}
.section--tight  { padding-block: calc(var(--section-y) * 0.72); }
.section--flush-top { padding-top: 0; }

/* Closes a band up against the one below it, so the NEXT section supplies the
   whole gap. Used where two bands share a ground colour and would otherwise
   read as one long stretch with a double space in the middle. Prefer this to
   .section--flush-top: zeroing the top of the lower band, which is what the
   podcast page did, leaves its heading sitting hard against the band above
   with no space at all, and the mockup has 80px there on desktop. */
.section--flush-bottom { padding-bottom: 0; }

/* Every page hero except Home's. Two jobs: the tighter vertical rhythm, and
   the smaller headline the spec calls for on Waitlist, Salon and Podcast. */
.page-hero { padding-block: var(--hero-y); }
.page-hero h1 { font-size: var(--t-h1-page); }

/* The three-step section-heading scale. See the note beside --t-h2. */
.h2-xl { font-size: var(--t-h2-xl); }
.h2-lg { font-size: var(--t-h2-lg); }
.h2-sm { font-size: var(--t-h2-sm); }

/* HOME BREATHES WIDER THAN THE INNER PAGES.
   Measured off the artboards, Home runs 56px bands on tablet and 86px on
   desktop where Waitlist, Salon and Podcast run 52 and 80. It is the longest
   page and the only one carrying photography in most of its bands, so the
   extra air is deliberate rather than an inconsistency in the design. Scoped
   to the body attribute so an inner page can never pick it up by accident. */
@media (min-width: 768px) {
  [data-page="home"] { --section-y: 56px; }
}
@media (min-width: 1120px) {
  [data-page="home"] { --section-y: 86px; }
}

/* Opts a single band back down to the standard rhythm. Two bands need it:
   the podcast teaser on Home, which the artboard runs at 80/52 while the
   bands either side of it run 86/56, and the closing banner on the podcast
   page, which runs 72 where its own page runs 80. Setting the token rather
   than the padding means the band still scales at every breakpoint. */
@media (min-width: 768px) {
  .section--calm  { --section-y: 52px; }
  .section--quiet { --section-y: 52px; }
}
@media (min-width: 1120px) {
  .section--calm  { --section-y: 80px; }
  .section--quiet { --section-y: 72px; }
}

/* A SECTION THAT OPENS ON A PORTRAIT NEEDS MORE ROOM ABOVE IT ON MOBILE.
   Two bands do this: "I'm Karis." on Home and the closing block on the
   waitlist page. Both lead with a blob portrait rather than a heading, and
   the mockup gives them 54px of top space against the standard 32. Without
   it the portrait sits too close to the band above and reads as clipped.
   Above 768px the portrait moves beside the copy instead of above it, so the
   standard rhythm is correct there and this only applies on phones. */
@media (max-width: 767px) {
  .section--lead-portrait { padding-top: 54px; }
}

.wrap {
  width: 100%;
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.prose { max-width: var(--measure); }

/* Long-form legal reading. Used on /privacy/ and /terms/, where the page is
   a run of h2 + p and needs breathing room between clauses rather than the
   tighter rhythm the marketing sections use. */
.legal h2 {
  margin-top: var(--space-6);
  font-size: var(--t-h3);
}
.legal h2:first-of-type { margin-top: var(--space-2); }
.legal p + p { margin-top: var(--space-3); }
.legal a { text-underline-offset: 3px; }

.stack       { display: flex; flex-direction: column; }
.stack--2  > * + * { margin-top: var(--space-2); }
.stack--3  > * + * { margin-top: var(--space-3); }
.stack--4  > * + * { margin-top: var(--space-4); }
.stack--5  > * + * { margin-top: var(--space-5); }
.stack--6  > * + * { margin-top: var(--space-6); }

/* Section grounds */
.ground-page  { background: var(--surface-page); color: var(--kd-navy); }
.ground-soft  { background: var(--surface-soft); color: var(--kd-navy); }
.ground-warm  { background: var(--surface-warm); color: var(--kd-navy); }
.ground-ink   { background: var(--surface-ink);  color: var(--text-on-ink); }
.ground-hero  { background: var(--gradient-hero); color: var(--kd-white); }

.ground-ink h1, .ground-ink h2, .ground-ink h3 { color: var(--text-on-ink); }
.ground-hero h1, .ground-hero h2 { color: var(--kd-white); }

/* ==========================================================================
   5. TYPE HELPERS
   ========================================================================== */

.overline {
  font-family: var(--font-ui);
  font-weight: var(--weight-bold);
  font-size: var(--t-overline);
  text-transform: uppercase;
  letter-spacing: var(--tracking-overline);
  color: var(--text-muted);
}
.overline--onink   { color: var(--kd-lavender); }
.overline--accent  { color: var(--accent); }
.overline--soft    { color: var(--accent-on-soft); }

.lead {
  font-family: var(--font-display);
  font-size: var(--t-lead);
  line-height: var(--leading-tight);
}

.body-lg { font-size: calc(var(--t-body) + 1px); line-height: var(--leading-body); }
.small   { font-size: var(--t-small); line-height: 1.55; }
.muted   { color: var(--text-muted); }

/* Card eyebrow — heavier and tighter than .overline */
.eyebrow {
  font-size: 13px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Numbered framework card heading */
.theme-num { font-family: var(--font-display); font-size: 18px; line-height: 1.2; margin-bottom: 6px; }

/* Small uppercase caption inside a tile */
.tile-meta {
  font-size: 9px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Standalone uppercase text link */
.link-overline {
  align-self: flex-start;
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--kd-lavender);
  /* 10px type is a 16px-tall target. The padding takes the tap area to the 44px
     the Link Spec asks for and the matching negative margin cancels it out, so
     the link sits exactly where the design puts it while being comfortably
     tappable. Padding, not height, because height would move the text. */
  padding-block: 14px;
  margin-block: -14px;
}
.link-overline:hover { color: var(--kd-white); }

/* Same link on a light ground. Lavender is a 1.6:1 mark on warm gray, so the
   light variant uses the AA-corrected accent instead. */
.link-overline--onlight { color: var(--accent); }
.link-overline--onlight:hover { color: var(--accent-hover); }

/* Reassurance line under a primary CTA */
.cta-note { font-size: 11px; line-height: 1.5; text-align: center; }

/* Lavender marker-pen highlight */
.highlight {
  background: linear-gradient(transparent 12%, var(--kd-lavender) 12% 86%, transparent 86%);
  padding: 0 0.08em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Left-ruled statement panel */
.statement {
  font-family: var(--font-display);
  font-size: var(--t-lead);
  line-height: 1.25;
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.statement--onhero {
  background: rgba(255, 255, 255, 0.14);
  border-left-color: var(--kd-white);
}
.statement--plain {
  background: none;
  padding: 0 0 0 var(--space-3);
  border-radius: 0;
}

/* ==========================================================================
   6. COMPONENTS
   ========================================================================== */

/* ---- Button ---- */
.btn {
  font-family: var(--font-ui);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-button);
  line-height: 1;
  border: var(--border-strong-w) solid transparent;
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-align: center;
  text-decoration: none;
  transition:
    background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
/* A disabled link still fires a click and would jump the page to the top on
   href="#". pointer-events stops that. The element stays in the tab order on
   purpose, announced as disabled, which is the accessible pattern: a screen
   reader user is told the button exists and is not ready yet, rather than
   finding it has silently vanished. */
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.btn--sm { padding: 9px 18px;  font-size: 12px; min-height: 44px; }
.btn--md { padding: 13px 26px; font-size: 13px; min-height: 44px; }
.btn--lg { padding: 17px 34px; font-size: 15px; min-height: 50px; }

.btn--primary {
  background: var(--accent);
  color: var(--kd-white);
  box-shadow: var(--shadow-accent);
}
.btn--primary:hover  { background: var(--accent-hover); color: var(--kd-white); }
.btn--primary:active { background: var(--accent-press); }

.btn--secondary {
  background: var(--kd-navy);
  color: var(--kd-warm-gray);
  border-color: var(--kd-navy);
}
.btn--secondary:hover { background: #2b4a5a; color: var(--kd-warm-gray); }

.btn--ondark {
  background: var(--kd-white);
  color: var(--kd-navy);
}
.btn--ondark:hover { background: var(--kd-warm-gray); color: var(--kd-navy); }

.btn--block { width: 100%; }

/* Buttons shrink to auto width from tablet, min 280px, left aligned.
   align-self matters as much as width here. Every one of these buttons sits in
   a .stack, which is a flex column, and a flex column stretches its children by
   default — so `width: auto` alone still produced a button running the whole
   1180px of the desktop column. That is the stretched-phone look this layer
   exists to remove. */
@media (min-width: 768px) {
  .btn--block { width: auto; min-width: 280px; align-self: flex-start; }
}

/* ---- Cards ---- */
.card {
  background: var(--surface-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 22px 20px;
}
.card--md    { border-radius: var(--radius-md); padding: 18px 20px; }
.card--lift  { box-shadow: var(--shadow-md); }
.card--soft  { background: var(--surface-soft); box-shadow: none; }
.card--warm  { background: var(--surface-warm); box-shadow: none; }

/* Translucent card on the navy ground */
.card--onink {
  background: rgba(247, 246, 244, 0.07);
  border-left: 3px solid var(--kd-lavender);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  box-shadow: none;
  padding: 16px 18px;
}

@media (min-width: 768px) {
  .card    { padding: 26px 24px; }
  .card--md { padding: 22px 24px; }
}

/* A CTA that sits inside a card, under the content it follows. The hairline
   rule is doing the work a heading would otherwise do: it says the list has
   ended and an action begins, without adding another heading level. */
.inline-cta {
  padding-top: var(--space-4);
  border-top: var(--border-hairline) solid var(--border-subtle);
}

/* ---- Arrow / marker lists ---- */
.marker-list { display: flex; flex-direction: column; gap: var(--space-3); }
.marker-list > li {
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: var(--space-2);
  font-size: var(--t-body);
  line-height: 1.5;
}
.marker-list > li::before {
  content: "\2192";                 /* → */
  color: var(--accent);
  font-weight: var(--weight-bold);
}
.marker-list--onink > li::before  { color: var(--kd-lavender); }
.marker-list--soft  > li::before  { color: var(--accent-on-soft); }
.marker-list--dot   > li::before  { content: "\00B7"; }
.marker-list--diamond > li::before { content: "\25C6"; font-weight: var(--weight-regular); }

/* Two columns of bullets from tablet up. An odd final item spans both columns
   rather than leaving a ragged half row — this is the seventh bullet on Home
   and on the waitlist page. */
@media (min-width: 768px) {
  .marker-list--2col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-6);
  }
  .marker-list--2col > li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ---- Blob portrait ---- */
.blob {
  position: relative;
  width: var(--blob-size, 180px);
  height: var(--blob-size, 180px);
  flex: none;
}
.blob::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(-9%, 6%);
  background: var(--blob-back, var(--kd-lavender));
  border-radius: var(--blob-back-radius, var(--blob-1));
}
.blob > picture {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
}
.blob img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--blob-pos, center top);
  border-radius: var(--blob-front-radius, var(--blob-0));
  box-shadow: var(--shadow-md);
}
.blob--0 { --blob-front-radius: var(--blob-0); --blob-back-radius: var(--blob-1); }
.blob--1 { --blob-front-radius: var(--blob-1); --blob-back-radius: var(--blob-2); }
.blob--2 { --blob-front-radius: var(--blob-2); --blob-back-radius: var(--blob-0); }

/* Size modifiers. Classes rather than inline styles so the CSP can stay
   strict — no 'unsafe-inline' is needed for style attributes anywhere. */
.blob--xs { --blob-size: 52px; }
.blob--sm { --blob-size: 130px; }
.blob--md { --blob-size: 180px; }
.blob--high { --blob-pos: center 20%; }

/* ---- Form fields ----
   Kept for any future inline form on the site. The waitlist itself no longer
   uses these: it runs Flodesk's own embed, which brings its own field markup
   and its own styles. See .fd-mount below. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label {
  font-size: 12px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  color: var(--kd-navy);
}
.field .optional {
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  letter-spacing: 0;
  text-transform: none;
}
.field > input {
  font-family: var(--font-ui);
  font-size: 16px;                 /* 16px stops iOS zooming on focus */
  font-weight: var(--weight-medium);
  color: var(--kd-navy);
  background: var(--kd-white);
  border: var(--border-regular) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  min-height: 48px;
  width: 100%;
  outline: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.field > input:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}
/* Invalid state. The system has no error red — do not introduce one. */
.field[data-invalid="true"] > input { border-color: var(--accent); border-width: var(--border-regular); }
.field-error {
  font-size: 11px;
  line-height: 1.45;
  color: var(--kd-navy);
  font-weight: var(--weight-bold);
}
.field-error:empty { display: none; }

/* Honeypot — off-screen, never focusable, invisible to assistive tech. */
.hp-field {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form-note { font-size: 10px; line-height: 1.55; color: var(--text-muted); }
.form-note a { color: var(--text-muted); text-decoration: underline; }
.form-note a:hover { color: var(--kd-navy); }

.form-status {
  font-size: 13px;
  line-height: 1.5;
  font-weight: var(--weight-bold);
  color: var(--kd-navy);
}
.form-status:empty { display: none; }

/* ---- Flodesk embed mount ----
   This is where the waitlist form actually lives. Flodesk writes its own
   markup and its own styles inside here, so keep local styling to the box
   around it. min-height reserves the space the form will occupy, which stops
   the page jumping as the embed arrives.

   Do NOT try to restyle the fields from here. Change the form's look inside
   Flodesk instead; anything forced from this stylesheet will break the next
   time Flodesk changes its markup. */
.fd-mount { min-height: 300px; }
.fd-mount [class*="fd-form"] { max-width: 100%; }

/* Shown only when the embed fails to load. See assets/js/waitlist.js. */
.fd-fallback { font-size: 14px; line-height: 1.55; color: var(--kd-navy); }

/* ---- Value strip ---- */
.value-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-ui);
  font-weight: var(--weight-bold);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-overline);
  color: var(--text-muted);
}
.value-strip .sep { opacity: 0.55; }

/* ==========================================================================
   7. HEADER / FOOTER / STICKY BAR
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  height: 54px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-inline: var(--gutter);
  background: rgba(247, 246, 244, 0.88);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: var(--border-hairline) solid var(--border-subtle);
}
/* The logo mark is 20px tall by design, which is too small a target to tap
   reliably. min-height grows the hit area to the full header without moving
   anything: the header is a fixed-height centred flex row, so the logo stays
   exactly where the design puts it. */
.site-header .wordmark { display: flex; align-items: center; min-height: 44px; }
.site-header .wordmark img { height: 20px; width: auto; }

.site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* :not(.btn) matters. The desktop header CTA is a .btn--primary sitting inside
   this nav, and a bare ".site-nav a" colour rule outranks .btn--primary on
   specificity, which painted navy text on the royal blue fill at 2.47:1. The
   nav's own colours are scoped away from buttons so a button always keeps the
   colours its own class gives it. */
.site-nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 8px;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.site-nav a:not(.btn) { color: var(--kd-navy); }
.site-nav a:not(.btn):hover { color: var(--accent); text-decoration: none; }
.site-nav a:not(.btn)[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.site-nav .pipe { color: var(--kd-navy-300); }
.site-nav .nav-full { display: none; }
.site-nav .header-cta { display: none; }

@media (min-width: 768px) {
  .site-header { height: 72px; }
  .site-header .wordmark img { height: 24px; }
  .site-nav { gap: 20px; font-size: 11px; }
  .site-nav a { padding-inline: 0; }
  .site-nav .pipe { display: none; }
  .site-nav .nav-short { display: none; }
  .site-nav .nav-full  { display: inline; }
  .site-nav .header-cta { display: inline-flex; margin-left: 4px; }
  .site-nav .header-cta[aria-current="page"] { border-bottom-color: transparent; }
}

@media (min-width: 1120px) {
  .site-header { height: 84px; }
  .site-header .wordmark img { height: 28px; }
  .site-nav { gap: 30px; font-size: 12px; }
}

.site-footer {
  /* The top and bottom padding look small because each link carries 14px of its
     own (see .site-footer a). Together they come back to the 18/30 the design
     draws, while every footer link is a full 44px tall to tap. */
  padding: 4px var(--gutter) 16px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-3);
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-top: var(--border-hairline) solid var(--border-subtle);
  background: var(--surface-page);
}
/* inline-flex so the 44px minimum grows the tap area without moving the text
   off the baseline the pipes and the copyright line sit on. */
.site-footer a {
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.site-footer a:hover { color: var(--kd-navy); }

/* Sticky bottom CTA bar — Home, mobile only. */
.sticky-cta {
  position: sticky;
  bottom: 0;
  z-index: 15;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 12px var(--gutter) 14px;
  padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  background: rgba(247, 246, 244, 0.94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: var(--border-hairline) solid var(--border-subtle);
}
.sticky-cta p {
  flex: 1;
  font-size: 11px;
  line-height: 1.35;
  color: var(--kd-navy-700);
}
@media (min-width: 768px) {
  .sticky-cta { display: none; }
}

/* ==========================================================================
   8. PAGE SECTIONS
   ========================================================================== */

/* ---- Hero (Home) ----
   Mobile: single column, white CTA card.
   768px+: a full-bleed 50/50 split. The gradient copy panel keeps the page
   gutter on its left, the portrait fills the right half edge to edge. The CTA
   card dissolves — the button sits inline beside its reassurance line. */
.hero { padding-block: 28px 30px; }
.hero .hero-cta {
  background: var(--kd-white);
  color: var(--kd-navy);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 18px;
  margin-top: var(--space-5);
}
.hero .hero-cta p { color: var(--kd-navy-700); }
.hero-media { display: none; }

@media (min-width: 768px) {
  .hero {
    padding-block: 0;
    display: grid;
    /* Tablet leans the split slightly towards the copy; 834px split dead even
       leaves the 44px H1 too little room. Desktop restores a true 50/50. */
    grid-template-columns: 1.12fr 0.88fr;
    align-items: stretch;
    min-height: 540px;
  }
  .hero .wrap {
    max-width: none;
    margin-inline: 0;
    align-self: center;
    padding-block: 48px;
    /* Right padding is tightened so the copy breathes into the split rather
       than hugging the photograph. */
    padding-inline: var(--gutter) var(--space-6);
  }
  .hero .body-lg  { max-width: 40ch; }
  .hero .statement { max-width: 32ch; }

  .hero .hero-cta {
    background: none;
    box-shadow: none;
    padding: 0;
    color: inherit;
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
  }
  .hero .hero-cta > * + * { margin-top: 0; }
  .hero .hero-cta .btn { flex: none; min-width: 0; }
  .hero .hero-cta p,
  .hero .hero-cta .cta-note {
    flex: 1 1 200px;
    color: rgba(255, 255, 255, 0.92);
    text-align: left;
    max-width: 30ch;
  }

  .hero-media { display: block; position: relative; overflow: hidden; }
  .hero-media picture { display: block; position: absolute; inset: 0; }
  .hero-media img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 18%;
  }
}

@media (min-width: 1120px) {
  .hero { min-height: 640px; grid-template-columns: 1fr 1fr; }
  /* The hero is full bleed, but its copy must start on the same vertical line
     as every capped section below it, or the page reads as two grids. This
     reproduces the left content edge of a 1180px .wrap exactly. */
  .hero .wrap {
    padding-block: 72px;
    padding-inline: calc(max(0px, (100vw - 1180px) / 2) + var(--gutter)) var(--space-8);
  }
}

/* ---- Logo wall ---- */
.logo-wall {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.logo-tile {
  background: var(--kd-white);
  border-radius: var(--radius-md);
  min-height: 68px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
}
.logo-tile img { max-height: 34px; width: auto; object-fit: contain; }
.logo-tile--text {
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 3px;
  padding: 12px 14px;
}
.logo-tile--text .name {
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.15;
}
.logo-tile--tall img { max-height: 44px; }
.logo-tile--short img { max-height: 30px; }

@media (min-width: 768px) {
  .logo-wall { grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
  .logo-tile { min-height: 76px; }
  .logo-tile--short img { max-height: 32px; }
  .logo-tile--tall  img { max-height: 52px; }
}

/* ---- Event photo credits (As seen & heard) ----
   Tablet and desktop only. These are evidence, so each one names its event. */
.credit-row { display: none; }

@media (min-width: 768px) {
  .credit-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
  }
  .credit { margin: 0; }
  .credit picture { display: block; }
  .credit img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    object-position: center 30%;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
  }
  .credit figcaption {
    margin-top: var(--space-2);
    font-size: 10px;
    font-weight: var(--weight-bold);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--text-muted);
  }
}

@media (min-width: 1120px) {
  .credit-row { gap: var(--space-5); }
  .credit img { height: 260px; }
  .credit figcaption { font-size: 11px; }
}

/* ---- Right now you might be feeling: list beside the window portrait ---- */
.feeling-media { display: none; }

@media (min-width: 768px) {
  .feeling-split {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: var(--space-6);
    align-items: center;
  }
  .feeling-media { display: block; }
  .feeling-media img {
    width: 100%;
    height: 300px;
    object-fit: cover;
    object-position: center 8%;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
  }
}

@media (min-width: 1120px) {
  .feeling-split { grid-template-columns: 1fr 380px; gap: var(--space-8); }
  .feeling-media img { height: 420px; }
}

/* ---- Closing CTA photo band ----
   Chalked blue on mobile. From 768px a full-bleed photograph under a navy
   veil, which is the only surface white type sits on here. */
.cta-band-media { display: none; }

@media (min-width: 768px) {
  /* Three layers, stacked with POSITIVE z-index only. Negative z-index was
     tried here and the photograph vanished behind the band's own background,
     which is a genuinely awkward bug to spot because everything measures as
     present and visible. Keep the numbers positive. */
  .cta-band {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    min-height: 420px;            /* the spec's number, was 460 */
    background: var(--kd-navy);   /* only ever seen if the photo fails */
    color: var(--kd-white);
    overflow: hidden;
  }
  /* 1. the photograph */
  .cta-band-media {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 1;
  }
  .cta-band-media picture { display: block; width: 100%; height: 100%; }
  .cta-band-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 22%;
  }
  /* 2. the navy veil that makes white type legible over it */
  .cta-band::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    background: linear-gradient(180deg, rgba(32, 56, 69, 0.42) 0%, rgba(32, 56, 69, 0.82) 100%);
  }
  /* 3. the words */
  .cta-band .wrap { position: relative; z-index: 3; }
  .cta-band h2 { color: var(--kd-white); }
  .cta-band .prose,
  .cta-band p { color: rgba(255, 255, 255, 0.94); }
}

@media (min-width: 1120px) {
  /* 42 on the artboard, a shade under the 44 the .h2-lg step gives. The line
     is long and sits over a photograph, so the design pulls it back here and
     only here: at tablet the .h2-lg step's 34px is already the right size. */
  .cta-band h2 { font-size: 42px; }
}

/* ---- Two-up card grids ---- */
.grid-2 { display: grid; gap: var(--space-4); }
.grid-3 { display: grid; gap: var(--space-3); }

@media (min-width: 768px) {
  .grid-2 { grid-template-columns: 1fr 1fr; align-items: stretch; }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
}

/* ---- Portrait + copy split (I'm Karis) ---- */
.split { display: flex; flex-direction: column; gap: var(--space-5); }
.split .blob { align-self: center; }

@media (min-width: 768px) {
  .split {
    flex-direction: row;
    align-items: center;
    gap: var(--space-6);
  }
  .split .blob { align-self: center; --blob-size: 260px; }
  .split .split-copy { flex: 1; }
}
@media (min-width: 1120px) {
  .split { gap: var(--space-8); align-items: center; }
  .split .blob { --blob-size: 360px; }
}

/* ---- Author row ---- */
.author-row { display: flex; align-items: center; gap: var(--space-3); }
.author-row .name { font-family: var(--font-display); font-size: 15px; line-height: 1.1; }

/* ---- Episode rows ---- */
.episode-list { display: flex; flex-direction: column; gap: 10px; }
.episode {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px;
  background: var(--kd-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  color: var(--kd-navy);
  min-height: 44px;
  transition: transform var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-fast) var(--ease-standard);
}
/* Lift, shadow and a chalked-blue fill, per the design spec. The fill is what
   makes it obvious the whole row is the target, not just the title. */
.episode:hover {
  text-decoration: none;
  background: var(--kd-chalked-blue);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.episode picture { flex: none; display: block; }
.episode img { width: 64px; height: 64px; border-radius: 10px; object-fit: cover; }
.episode .meta { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.episode .ep-num {
  font-size: 9px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.episode .ep-title { font-size: 13px; line-height: 1.4; }
.episode .arrow { flex: none; padding-right: 6px; color: var(--accent); font-size: 14px; }

/* A row with no title yet. Deliberately inert: no link, no hover, no arrow, so
   the page never ships a dead anchor. No page uses this at the moment. It is
   kept because it is the right treatment if a row ever needs to sit there
   unlinked, and it costs two lines. */
.episode--placeholder { cursor: default; box-shadow: var(--shadow-xs); }
.episode--placeholder .ep-title { color: var(--text-muted); }

/* An episode that is recorded but not out yet. It is a <div>, not an <a>, so
   there is nothing to click and nothing to tab into. It keeps its artwork and
   its title because both are true; what it loses is the arrow and the hover,
   which are the two things that promise a destination. The badge carries the
   date, so nobody has to guess whether the row is broken. */
.episode--soon {
  cursor: default;
  background: var(--kd-warm-gray);
  box-shadow: var(--shadow-xs);
}
.episode--soon .ep-title { color: var(--text-muted); }
.ep-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--kd-lavender);
  color: var(--kd-navy);
  font-size: 9px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}

/* The one card standing in for every episode that has no row of its own yet.
   Tinted, so it reads as a way through to the archive rather than as another
   episode. It always sits last, and spans the full width on the two-column
   layouts because it is not an episode competing with its neighbour. */
.episode--archive { background: var(--kd-chalked-blue); }
@media (min-width: 768px) {
  .episode-archive-item { grid-column: 1 / -1; }
}

.list-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

/* Episode rows on the navy podcast teaser */
.episode--onink {
  background: rgba(247, 246, 244, 0.07);
  color: var(--text-on-ink);
  box-shadow: none;
  padding: 8px;
}
.episode--onink:hover { background: rgba(247, 246, 244, 0.12); box-shadow: none; }
.episode--onink .ep-num { color: var(--kd-lavender); }
.episode--onink .arrow  { color: var(--kd-lavender); }

/* Episode rows go two-up from tablet. Thumbnails 64 mobile / 62 tablet /
   78 desktop, per the spec. */
@media (min-width: 768px) {
  /* Both lists, not just the full archive. A three-item teaser stacked full
     width across a 1180px column reads as three near-empty bars, which is
     precisely the stretched-phone problem the tablet and desktop layers exist
     to fix. */
  .episode-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    align-items: stretch;
  }
  .episode img { width: 62px; height: 62px; }
  /* An odd last row spans both columns rather than leaving a gap.
     The grid child is the <li>, NOT the .episode link inside it. Targeting
     .episode here looks right and silently does nothing. */
  .episode-list > li { display: flex; }
  .episode-list > li > .episode { flex: 1; }
  .episode-list > li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (min-width: 1120px) {
  .episode { padding: 12px; }
  .episode img { width: 78px; height: 78px; border-radius: 12px; }
  .episode .ep-title { font-size: 14px; }
}

/* ---- Listen pills ---- */
.pill-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pill {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--space-4);
  border: var(--border-regular) solid var(--kd-navy);
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--kd-navy);
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
.pill:hover { background: var(--kd-navy); color: var(--kd-warm-gray); text-decoration: none; }

/* ---- Podcast show hero ---- */
.show-head { display: flex; align-items: center; gap: var(--space-3); }
.show-head picture { flex: none; display: block; }
.show-head img {
  width: 104px; height: 104px;
  border-radius: var(--radius-md);
  object-fit: cover;
}
/* The Home teaser runs the cover 4px larger than the Podcast page header. */
.show-head img.show-cover { width: 108px; height: 108px; }

@media (min-width: 768px) {
  .show-head { gap: var(--space-5); }
  .show-head img { width: 240px; height: 240px; }
  .show-head img.show-cover { width: 180px; height: 180px; }
}

@media (min-width: 1120px) {
  .show-head { gap: var(--space-6); }
  .show-head img { width: 340px; height: 340px; }
  .show-head img.show-cover { width: 220px; height: 220px; }
}

.logo-tile picture { display: block; }

/* ---- Centred CTA block ---- */
.cta-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-4);
}
.cta-block .prose { text-align: center; }

/* ---- Big figure (CV Cliffnotes) ---- */
.figure-lg {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  color: var(--kd-lavender);
  margin-bottom: 6px;
}

/* ---- Inner page heroes ----
   Home carries the 60px H1 on desktop. Waitlist, Salon, Podcast and the
   thank-you screen sit a step below it so Home stays the loudest page.

   This used to be a single hard-coded 53px that only applied above 1120px,
   which meant the step down existed on desktop and nowhere else: on a phone
   and on a tablet all five pages shouted at exactly the same volume, and the
   mockups have them at 30 and 40 against Home's 38 and 44. The size now comes
   from --t-h1-page, which is set at all three breakpoints, and is applied by
   the .page-hero rule in the layout section. Nothing is needed here. */

/* ---- Waitlist page desktop split ----
   The spec says top: 40px. A sticky element is positioned against the
   viewport, not the section, and the header is 84px tall on desktop, so 40px
   would park the form under it. 104px is the same 20px of breathing room the
   design shows, measured from the bottom of the header. */
.waitlist-hero .form-card { margin-top: var(--space-5); }

@media (min-width: 1120px) {
  .waitlist-hero .wrap {
    display: grid;
    grid-template-columns: 1fr 440px;
    gap: var(--space-8);
    align-items: start;
  }
  .waitlist-hero .form-card {
    position: sticky;
    top: 104px;
    margin-top: 0;
  }
}

/* ---- Leadership Salon ----
   Mobile is one chalked-blue section. From 768px the hero splits and a
   two-photo credit band follows it on tan. */
.salon-media { display: none; }
/* The whole band section is pulled, not just its contents, or mobile gets an
   empty tan strip between the hero and the value line. */
.salon-band-section { display: none; }

@media (min-width: 768px) {
  .salon-band-section { display: block; }
  .salon-hero {
    padding-block: 0;
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
    align-items: stretch;
    min-height: 520px;
  }
  .salon-hero .wrap {
    max-width: none;
    margin-inline: 0;
    align-self: center;
    padding-block: 48px;
    padding-inline: var(--gutter) var(--space-6);
  }
  .salon-media { display: block; position: relative; overflow: hidden; }
  .salon-media picture { display: block; position: absolute; inset: 0; }
  .salon-media img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 25%;
  }

  .salon-band {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-5);
  }
  .salon-band img {
    width: 100%;
    height: 240px;
    object-fit: cover;
    object-position: center 30%;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
  }
}

@media (min-width: 1120px) {
  .salon-hero { min-height: 600px; grid-template-columns: 1fr 1fr; }
  .salon-hero .wrap {
    padding-block: 72px;
    padding-inline: calc(max(0px, (100vw - 1180px) / 2) + var(--gutter)) var(--space-8);
  }
  .salon-band img { height: 320px; }
  .salon-card { max-width: 560px; }
}

/* ---- Thank you split hero ----
   The base padding lives here, above the split, so the media query that zeroes
   it wins on cascade order. Do not move a bare `.thanks` rule below this. */
.thanks { padding-block: 44px 40px; }
.thanks-media { display: none; }

@media (min-width: 768px) {
  .thanks {
    padding-block: 0;
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
    align-items: stretch;
    min-height: 520px;
  }
  .thanks .wrap {
    max-width: none;
    margin-inline: 0;
    align-self: center;
    padding-block: 56px;
    padding-inline: var(--gutter) var(--space-6);
  }
  .thanks .blob { --blob-size: 160px; }
  .thanks-media { display: block; position: relative; overflow: hidden; }
  .thanks-media picture { display: block; position: absolute; inset: 0; }
  .thanks-media img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 18%;
  }
}

@media (min-width: 1120px) {
  .thanks { min-height: 600px; grid-template-columns: 1fr 1fr; }
  .thanks .wrap {
    padding-block: 80px;
    padding-inline: calc(max(0px, (100vw - 1180px) / 2) + var(--gutter)) var(--space-8);
  }
}

/* Tan-filled emphasis paragraph */
.panel-warm {
  padding: 16px 18px;
  background: var(--kd-tan);
  border-radius: var(--radius-md);
}

.form-foot { margin-top: var(--space-4); }

.form-card {
  background: var(--kd-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 20px 18px;
}
@media (min-width: 768px) { .form-card { padding: 26px 24px; } }


/* ==========================================================================
   9. MOTION
   Ease-out fade plus 8px rise on section entry. No bounce, no loops.
   JS adds .is-armed; without JS nothing is ever hidden.
   ========================================================================== */

.reveal.is-armed {
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
.reveal.is-armed.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal.is-armed { opacity: 1; transform: none; }
}

/* ==========================================================================
   10. PRINT
   ========================================================================== */

@media print {
  .site-header, .sticky-cta, .btn, .site-nav { display: none !important; }
  body { background: #fff; color: #000; }
  .ground-ink, .ground-hero { background: #fff !important; color: #000 !important; }
  .ground-ink h1, .ground-ink h2, .ground-hero h1 { color: #000 !important; }
}

/* ==========================================================================
   11. INSTAGRAM LANDING PAGE  (/ig/)
   --------------------------------------------------------------------------
   A standalone single-screen link hub for the Instagram and LinkedIn bios. It
   is not part of the four-page site: no navigation, no footer links, one job.
   It is an orphan on purpose, reachable only from a bio field.

   Everything here is scoped under body[data-page="links"] so none of it can
   reach the main pages. The attribute value is "links" rather than "ig"
   because it names a layout, not an address, and the address moved on
   2 September 2026 without the layout changing. The page is designed at 390px and the column caps at
   480px, because a link hub read on a desktop should stay a phone-shaped
   column rather than stretch into a banner.

   THE ONE HARD CONSTRAINT: all four tiles must be reachable on a 390x844
   screen without scrolling. The header, the four 76px tiles and their gaps
   land at roughly 830px. Adding a fifth tile breaks that, and the value strip
   is what gets cut to make room, never a tile.
   ========================================================================== */

body[data-page="links"] {
  /* Navy surround so the card reads as a card on a large screen. On a phone
     the card fills the viewport and the surround is never seen. */
  background: var(--kd-navy);
}

.link-page {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 0;
}

.link-card {
  width: 100%;
  max-width: 480px;
  background: var(--surface-page);
  color: var(--kd-navy);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* ---- Header ---- */
.link-head {
  background: var(--gradient-brand);
  padding: 40px var(--gutter) 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
}

/* A plain circle rather than the site's organic blob shapes. The blobs belong
   to editorial layouts; a bio avatar is read as a profile picture and every
   platform it sits beside draws it round. */
.link-avatar {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--kd-lavender);
  flex: none;
}
/* The <picture> needs the size too. Without it the picture stays an inline box
   of automatic height, the img's height:100% has nothing to resolve against,
   and the crop silently becomes the whole portrait shrunk into the circle. */
.link-avatar picture { display: block; width: 100%; height: 100%; }
.link-avatar img {
  width: 100%;
  height: 100%;
  /* The asset is already square and already cropped to the face, so cover has
     nothing to do here. It stays as insurance: if the file is ever swapped for
     a rectangular one, the circle distorts nothing, it just crops. */
  object-fit: cover;
  display: block;
}

.link-wordmark img { height: 30px; width: auto; display: block; }

.link-intro {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  /* Not pure white. The gradient is light at its lavender end and full-strength
     white on it is a hard, glaring edge; 92% sits back without losing contrast
     against the royal blue the paragraph actually starts on. */
  color: rgba(255, 255, 255, 0.92);
  text-wrap: pretty;
}

.link-statement {
  margin: 0;
  font-family: var(--font-display);
  font-size: 18px;
  line-height: 1.3;
  color: var(--kd-white);
}

/* ---- Tiles ---- */
.link-tiles {
  padding: 26px var(--gutter) 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tile {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 76px;
  padding: 16px;
  border-radius: var(--radius-lg);
  background: var(--kd-white);
  color: var(--kd-navy);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  /* 180ms, written as a literal because the brief names that exact figure and
     it sits between --dur-fast and --dur-normal. Adding a fourth duration to
     the scale for one component would be worse than this comment. */
  transition: background 180ms var(--ease-out),
              box-shadow 180ms var(--ease-out),
              transform 180ms var(--ease-out);
}
.tile:hover {
  background: var(--kd-chalked-blue);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* The waitlist tile. Filled, so the eye lands on it first without needing a
   label that says "start here". */
.tile--primary {
  background: var(--accent);
  color: var(--kd-white);
  box-shadow: var(--shadow-accent);
}
.tile--primary:hover {
  background: var(--kd-royal-700);
  box-shadow: var(--shadow-accent);
}

.tile-thumb {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 10px;
  object-fit: cover;
}

.tile-text { flex: 1; display: flex; flex-direction: column; gap: 4px; }

.tile-title {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 1.25;
  color: inherit;
}

.tile-sub { font-size: 11px; line-height: 1.45; color: var(--text-muted); }
.tile--primary .tile-sub { color: rgba(255, 255, 255, 0.85); }

.tile-arrow { flex: none; font-size: 16px; color: var(--accent); }
.tile--primary .tile-arrow { color: var(--kd-white); }

/* ---- Value strip and footer ---- */
.link-values { padding: 6px var(--gutter) 26px; }
/* Smaller and tighter than the strip on the main pages. Four words plus three
   dots have to hold one line inside a 390px column, and the site-wide gap of
   16px spends 96px on white space before a letter is drawn. */
.link-values .value-strip {
  justify-content: center;
  font-size: 9px;
  gap: 7px;
  flex-wrap: nowrap;
}

.link-foot {
  margin-top: auto;
  padding: 16px var(--gutter) 30px;
  display: flex;
  justify-content: center;
  font-size: 9px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-top: var(--border-hairline) solid var(--border-subtle);
}

/* On anything wider than a phone the card stops filling the screen and becomes
   a floating card on the navy, which is how the design draws it. */
@media (min-width: 560px) {
  .link-page { align-items: center; padding: 40px 0; }
  .link-card {
    min-height: 0;
    border-radius: 38px;
    overflow: hidden;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
  }
}
