/* =========================================================================
   scoshow.com

   Two independent axes:

     SKIN   day / night   — prefers-color-scheme, pure CSS, no JS, no flash.
                            (?skin=night forces one, for review only.)
     STATE  live / offline — comes from Twitch data, set server-side as a class
                            on <body>. Nothing here assumes night means live.

   All four combinations render. The only thing night owns exclusively is the
   glow: it is a skin choice, not a state signal.

   Values are lifted from DayCool.dc.html and ComboNight.dc.html.
   ========================================================================= */

/* ---------- tokens: DAY (the default, cool paper) ---------- */

/* ---------- the faces, and what each one is for ----------

   The rule is by REGION, not by content type:

   --f-hand   Shantell  Scott's voice, and the shelves. Every section heading
                        and aside, the note, CTA cards, the OFF AIR / ON AIR
                        chips, the footer — plus every caption on the Still
                        Single shelf, the camera roll and the shorts row.
   --f-body   Karla     the whole timeline card interior: video and stream
                        titles, post text, short-card captions, platform
                        labels and date/meta lines. Also the hero dek and the
                        note's body copy.
   --f-serif  Lora      the hero title. That is now its only job on the page.
   --f-display Gabarito the wordmark, and nothing else.

   So: the shelves speak in Scott's hand, the timeline is a uniform block of
   Karla, and Lora is reserved for the one thing at the top. The timeline's
   section heading and aside stay Shantell — those are page voice, like every
   other section heading, and sit outside the cards.                        */

:root {
  --f-display: 'Gabarito', system-ui, sans-serif;
  --f-hand:    'Shantell Sans', system-ui, sans-serif;
  --f-serif:   'Lora', Georgia, serif;
  --f-body:    'Karla', system-ui, sans-serif;

  --paper:     #f3f2f6;
  --card:      #fcfbfe;
  --rule:      #dcd9e4;

  --ink:       #232030;
  --ink-mark:  #141210;
  --body:      #453f52;
  --soft:      #555062;
  --muted:     #706a80;
  --muted-2:   #6a637a;

  --well:        #e9e6f0;
  --well-ink:    #b3adc2;
  --well-border: transparent;

  --shadow-card:     0 2px 8px rgba(35, 32, 48, 0.07);
  --shadow-hero:     0 2px 10px rgba(35, 32, 48, 0.08);
  --shadow-polaroid: 0 3px 12px rgba(35, 32, 48, 0.12);
  --shadow-tape:     0 1px 2px rgba(35, 32, 48, 0.1);
  --tape-neutral:    rgba(178, 173, 198, 0.55);

  /* wordmark — S H O W */
  --mark-s: #c23c38;
  --mark-h: #cf7028;
  --mark-o: #3f7d4e;
  --mark-w: #41598f;

  /* accents, per AccentOptions.dc.html: one hue per job.
     --watch-deep is the day board's own second scarlet; see README. */
  --live:       #c23c38;
  --watch:      #e8402f;
  --watch-deep: #c73325;
  --join:       #3f7d4e;
  --join-ink:   #fcfbfe;
  --link:       #2563eb;
  --link-hover: #1d4ed8;
  --focus:      #2563eb;

  /* platform tape + icons */
  --tape-youtube:   rgba(224, 0, 0, 0.8);
  --tape-twitch:    rgba(122, 46, 230, 0.75);
  --tape-bluesky:   rgba(11, 110, 214, 0.75);
  --tape-instagram: rgba(198, 35, 96, 0.75);
  --tape-threads:   rgba(18, 137, 124, 0.75);

  --ico-youtube:   #e00000;
  --ico-twitch:    #7a2ee6;
  --ico-bluesky:   #0b6ed6;
  --ico-instagram: #c62360;
  --ico-threads:   #12897c;

  /* night-only effects, neutralised on day */
  --glow-chip:   none;
  --glow-stage:  var(--shadow-hero);

  --gutter: 72px;
}

/* ---------- tokens: NIGHT (purple-black) ---------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-skin="day"]) { color-scheme: dark; }
}

:root[data-skin="night"] { color-scheme: dark; }

/* One block of overrides, applied by either the media query or the explicit
   attribute, so day and night can never drift apart. */
:root[data-skin="night"] {
  --paper:     #0d0b14;
  --card:      #16121f;
  --rule:      #2a2338;

  --ink:       #f2eef8;
  --ink-mark:  #f7f2e6;
  --body:      #cfc8dd;
  --soft:      #cfc8dd;
  --muted:     #a79fb8;
  --muted-2:   #8b84a0;

  --well:        #100c18;
  --well-ink:    #4a4258;
  --well-border: #2a2338;

  --shadow-card:     0 3px 12px rgba(0, 0, 0, 0.35);
  --shadow-hero:     0 4px 16px rgba(0, 0, 0, 0.35);
  --shadow-polaroid: 0 4px 16px rgba(0, 0, 0, 0.45);
  --shadow-tape:     0 1px 2px rgba(0, 0, 0, 0.3);
  --tape-neutral:    rgba(178, 173, 198, 0.45);

  --mark-s: #e0645f;
  --mark-h: #e8a45c;
  --mark-o: #74b585;
  --mark-w: #7aa3e0;

  --live:       #f0413c;
  --watch:      #ff6247;
  --watch-deep: #ff6247;
  --join:       #74b585;
  --join-ink:   #0d0b14;
  --link:       #5fb8e8;
  --link-hover: #8ed1f2;
  --focus:      #8ed1f2;

  --tape-youtube:   rgba(255, 97, 89, 0.85);
  --tape-twitch:    rgba(169, 112, 255, 0.85);
  --tape-bluesky:   rgba(82, 169, 255, 0.85);
  --tape-instagram: rgba(242, 96, 158, 0.85);
  --tape-threads:   rgba(26, 171, 155, 0.85);

  --ico-youtube:   #ff6159;
  --ico-twitch:    #a970ff;
  --ico-bluesky:   #52a9ff;
  --ico-instagram: #f2609e;
  --ico-threads:   #1aab9b;

  /* the glow — night skin only, in either state */
  --glow-chip:  0 0 18px rgba(240, 65, 60, 0.35);
  --glow-stage: 0 0 64px rgba(240, 65, 60, 0.18), 0 4px 16px rgba(0, 0, 0, 0.4);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-skin="day"]) {
    --paper:     #0d0b14;
    --card:      #16121f;
    --rule:      #2a2338;

    --ink:       #f2eef8;
    --ink-mark:  #f7f2e6;
    --body:      #cfc8dd;
    --soft:      #cfc8dd;
    --muted:     #a79fb8;
    --muted-2:   #8b84a0;

    --well:        #100c18;
    --well-ink:    #4a4258;
    --well-border: #2a2338;

    --shadow-card:     0 3px 12px rgba(0, 0, 0, 0.35);
    --shadow-hero:     0 4px 16px rgba(0, 0, 0, 0.35);
    --shadow-polaroid: 0 4px 16px rgba(0, 0, 0, 0.45);
    --shadow-tape:     0 1px 2px rgba(0, 0, 0, 0.3);
    --tape-neutral:    rgba(178, 173, 198, 0.45);

    --mark-s: #e0645f;
    --mark-h: #e8a45c;
    --mark-o: #74b585;
    --mark-w: #7aa3e0;

    --live:       #f0413c;
    --watch:      #ff6247;
    --watch-deep: #ff6247;
    --join:       #74b585;
    --join-ink:   #0d0b14;
    --link:       #5fb8e8;
    --link-hover: #8ed1f2;
    --focus:      #8ed1f2;

    --tape-youtube:   rgba(255, 97, 89, 0.85);
    --tape-twitch:    rgba(169, 112, 255, 0.85);
    --tape-bluesky:   rgba(82, 169, 255, 0.85);
    --tape-instagram: rgba(242, 96, 158, 0.85);
    --tape-threads:   rgba(26, 171, 155, 0.85);

    --ico-youtube:   #ff6159;
    --ico-twitch:    #a970ff;
    --ico-bluesky:   #52a9ff;
    --ico-instagram: #f2609e;
    --ico-threads:   #1aab9b;

    --glow-chip:  0 0 18px rgba(240, 65, 60, 0.35);
    --glow-stage: 0 0 64px rgba(240, 65, 60, 0.18), 0 4px 16px rgba(0, 0, 0, 0.4);
  }
}


/* ---------- base ---------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.5;
}

img { max-width: 100%; }

/* Spacing is done with gap and explicit margins, not default paragraph margins.
   .note__card restores its own further down. */
.page p, .page h1, .page h2, .page figure { margin: 0; }

a { color: var(--link); }
a:hover { color: var(--link-hover); }

/* Focus rings must never be clipped — no overflow:hidden on any card. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Removed from the visual page, still read aloud. Used for the signup label,
   the live hero's heading, and the "(opens in a new tab)" note on every
   outbound link. */
.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;
}

.page {
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
}

/* Board paddings, section by section. One breakpoint collapses the asymmetry. */
.sec { padding-left: var(--pl, var(--gutter)); padding-right: var(--pr, var(--gutter)); }


/* ---------- shared card furniture ---------- */

.card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-card);
  transform: rotate(var(--rot, 0deg));
}

/* The bit of tape at the top of a card. Colour comes from --tape. */
.tape {
  position: absolute;
  top: -9px;
  left: var(--tape-left, 24px);
  width: var(--tape-w, 56px);
  height: var(--tape-h, 16px);
  background: var(--tape, var(--tape-neutral));
  pointer-events: none;
}

/* Whole-card links: inherit type colour, lose the underline, keep the ring. */
.plain { color: inherit; text-decoration: none; display: block; }
.plain:hover { color: inherit; }
.plain:hover .u { text-decoration: underline; }

.hand   { font-family: var(--f-hand); }
.serif  { font-family: var(--f-serif); }
.u      { text-decoration: underline; }

/* A whole card is one <a>, so its inner text nodes are spans. Spans are inline
   by default, which silently drops every vertical margin below — hence this. */
.cap, .roll__cap, .lead, .sub,
.tl-card__title, .tl-card__meta { display: block; }
/* .tl-card__text sets its own display (-webkit-box, for the line clamp). */

.eyebrow {
  font-family: var(--f-hand);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--muted);
}

.sec-head {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}
.sec-head h2 {
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 26px;
  margin: 0;
  line-height: 1.25;
}
.sec-head .aside {
  font-family: var(--f-hand);
  font-size: 15px;
  color: var(--muted);
}

/* Placeholder well — an empty photo slot, drawn on both boards. */
.well {
  background: var(--well);
  border: 1px solid var(--well-border);
  color: var(--well-ink);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The little hand-drawn arrow on "more" cards. */
.more-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}


/* ---------- masthead ---------- */

.masthead {
  --pl: 72px; --pr: 72px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding-top: 26px;
  padding-bottom: 16px;
  flex-wrap: wrap;
}

.wordmark {
  font-family: var(--f-display);
  font-weight: 900;
  font-size: 58px;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--ink-mark);
  text-decoration: none;
  display: block;
}
.wordmark:hover { color: var(--ink-mark); }
.wordmark .s { color: var(--mark-s); }
.wordmark .h { color: var(--mark-h); }
.wordmark .o { color: var(--mark-o); }
.wordmark .w { color: var(--mark-w); }

.tagline {
  font-family: var(--f-hand);
  font-size: 14px;
  color: var(--muted);
  margin-top: 2px;
}

.masthead__right {
  display: flex;
  align-items: center;
  gap: 22px;
  color: var(--muted);
  padding-bottom: 12px;
  flex-wrap: wrap;
}

.socials { display: flex; align-items: center; gap: 22px; }
.socials a { color: var(--muted); display: inline-flex; }
.socials a:hover { color: var(--ink); }

/* OFF AIR chip — deliberately neutral grey. Absence is not an action. */
.chip-off {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1.5px solid #8d8699;
  color: #5d5670;
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 6px 13px;
  border-radius: 999px;
  white-space: nowrap;
}
.chip-off .dot {
  width: 7px; height: 7px;
  border-radius: 999px;
  background: #8d8699;
}
:root[data-skin="night"] .chip-off { border-color: #4a4258; color: var(--muted); }
:root[data-skin="night"] .chip-off .dot { background: #4a4258; }
@media (prefers-color-scheme: dark) {
  :root:not([data-skin="day"]) .chip-off { border-color: #4a4258; color: var(--muted); }
  :root:not([data-skin="day"]) .chip-off .dot { background: #4a4258; }
}


/* ---------- hero, OFFLINE ---------- */

.hero {
  --pl: 72px; --pr: 72px;
  display: flex;
  gap: 56px;
  padding-top: 32px;
  align-items: center;
}

/* The board draws the framed thumbnail at 780px inside a 1296px content row —
   810px with its padding and border, or 62.5%. It must hold that share: with a
   shrinkable basis, a long title in the text column was clawing width back off
   the thumbnail. flex-shrink:0 plus a percentage basis pins the proportion, and
   the text column takes whatever is left (1296 - 810 - 56 gap = 430px). */
.hero__frame {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 14px;
  box-shadow: var(--shadow-hero);
  flex: 0 0 62.5%;
  min-width: 0;
}

.hero__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--well);
  display: block;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
}
.hero__stage img,
.hero__stage iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
}

.hero__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.hero__play span {
  width: 76px; height: 76px;
  border-radius: 999px;
  background: rgba(20, 18, 16, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero__caption {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-top: 12px;
  padding: 0 2px;
  font-family: var(--f-hand);
  font-size: 14px;
  color: var(--muted);
  flex-wrap: wrap;
}
.hero__caption .when { font-size: 13px; color: var(--muted-2); }

/* basis 0 so the column is sized by what's left over, never by its own text */
.hero__text {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}
.hero__kicker {
  font-family: var(--f-hand);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--watch-deep);
}
.hero__title {
  font-family: var(--f-serif);
  font-weight: 600;
  font-size: 31px;
  line-height: 1.3;
  margin: 0;
}
.hero__title a { color: inherit; text-decoration: none; }
.hero__title a:hover { text-decoration: underline; }
/* Real descriptions run long where the board's dek was one hand-written line.
   Three lines, then clipped — the full text is on YouTube, one click away. */
.hero__dek {
  font-size: 16px;
  line-height: 1.65;
  color: var(--soft);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

.btn-watch {
  align-self: flex-start;
  font-family: var(--f-hand);
  font-weight: 700;
  background: var(--watch-deep);
  color: #fcfbfe;
  font-size: 16px;
  padding: 12px 26px;
  text-decoration: none;
  margin-top: 6px;
  display: inline-block;
}
.btn-watch:hover { color: #fcfbfe; filter: brightness(1.08); }
:root[data-skin="night"] .btn-watch { color: #16121f; }
@media (prefers-color-scheme: dark) {
  :root:not([data-skin="day"]) .btn-watch { color: #16121f; }
}


/* ---------- hero, LIVE ---------- */

.hero-live { --pl: 72px; --pr: 72px; padding-top: 24px; }

.hero-live__bar {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.chip-on {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 1.5px solid var(--live);
  color: var(--live);
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.1em;
  padding: 8px 16px;
  box-shadow: var(--glow-chip);   /* night only */
  white-space: nowrap;
}
.chip-on .dot {
  width: 8px; height: 8px;
  border-radius: 999px;
  background: var(--live);
}

.hero-live__now {
  font-family: var(--f-hand);
  font-weight: 500;
  font-size: 16px;
  color: var(--live);
}
.hero-live__count {
  font-family: var(--f-hand);
  font-size: 13px;
  color: var(--muted);
}
.hero-live__who {
  font-family: var(--f-hand);
  font-size: 14px;
  color: var(--muted);
  margin: -10px 0 20px 2px;
}

.hero-live__row {
  display: flex;
  gap: 36px;
  align-items: stretch;
}

/* Same reasoning as .hero__frame: the night board draws the player at 800px
   (830 framed) in the 1296px row, so 64%, and a long stream title in the
   caption below must not be able to shrink it. THE ROOM takes the remainder. */
.hero-live__player {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 14px;
  box-shadow: var(--glow-stage);
  flex: 0 0 64%;
  min-width: 0;
}
.hero-live__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--well);
}
.hero-live__stage iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* Revealed by site.js: at once on Safari (its tracking protection stalls the
   embed after the ad), after 30s elsewhere. Quiet on purpose — it also shows
   for viewers whose player is fine. */
.hero-live__stuck {
  margin: 6px 0 0;
  padding: 0 2px;
  font-family: var(--f-hand);
  font-size: 13px;
  color: var(--muted-2);
}

.room {
  flex: 1 1 0;
  min-width: 0;
  background: var(--card);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-hero);
  display: flex;
  flex-direction: column;
}
.room__head {
  margin: 0;
  padding: 14px 20px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.1em;
  color: var(--muted);
}
.room__chat { flex: 1 1 auto; min-height: 360px; position: relative; }
.room__chat iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.room__fallback {
  padding: 20px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--body);
}


/* ---------- the note ---------- */

.note {
  --pl: 136px; --pr: 72px;
  display: flex;
  gap: 60px;
  padding-top: 84px;
  align-items: center;
}

.note__card {
  background: var(--card);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-hero);
  padding: 38px 42px;
  max-width: 700px;
  flex: 1 1 460px;
  min-width: 0;
}
.note__hi {
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 20px;
  margin: 0 0 14px;
}
.note__card p {
  font-size: 16px;
  line-height: 1.75;
  color: var(--body);
  margin: 0 0 14px;
}
.note__card p:last-of-type { margin-bottom: 24px; }
.note__fine { font-size: 13px; color: var(--muted-2); margin-top: 14px; }

/* signup form — a real form, styled to look like the board's ruled line */
.signup { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.signup input[type="email"] {
  width: 300px;
  max-width: 100%;
  border: 0;
  border-bottom: 1.5px solid var(--ink);
  background: transparent;
  color: var(--ink);
  padding: 6px 2px;
  font-family: var(--f-hand);
  font-size: 15px;
  border-radius: 0;
}
.signup input[type="email"]::placeholder { color: var(--muted-2); opacity: 1; }
.signup button {
  font-family: var(--f-hand);
  font-weight: 700;
  background: var(--join);
  color: var(--join-ink);
  font-size: 15px;
  padding: 11px 22px;
  border: 0;
  cursor: pointer;
  border-radius: 0;
}
.signup button:hover { filter: brightness(1.07); }
:root[data-skin="night"] .signup input[type="email"] { border-bottom-color: var(--muted); }
@media (prefers-color-scheme: dark) {
  :root:not([data-skin="day"]) .signup input[type="email"] { border-bottom-color: var(--muted); }
}

/* honeypot — off-screen, never focusable, never announced */
.hp { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

.signup-msg {
  font-family: var(--f-hand);
  font-size: 18px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--ink-mark);
  margin: 12px 0 0;
  padding: 14px 18px;
  border-radius: 12px;
  background: var(--paper);
  border: 2px solid var(--mark-h);
}
.signup-msg[data-tone="error"] {
  color: var(--live);
  border-color: var(--live);
}

/* polaroid */
.polaroid { position: relative; transform: rotate(1.6deg); flex: 0 0 auto; }
.polaroid .tape {
  left: 92px; top: -11px;
  width: 80px; height: 20px;
  background: var(--tape-neutral);
  box-shadow: var(--shadow-tape);
}
.polaroid__inner {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 12px 12px 14px;
  box-shadow: var(--shadow-polaroid);
}
.polaroid img {
  width: 250px;
  height: 270px;
  object-fit: cover;
  object-position: 50% 20%;
  display: block;
}
.polaroid figcaption {
  font-family: var(--f-hand);
  font-weight: 500;
  font-size: 14px;
  color: var(--soft);
  margin-top: 12px;
  text-align: center;
}


/* ---------- still single shelf ---------- */

.shelf { --pl: 120px; --pr: 104px; padding-top: 84px; }
.shelf .sec-head h2 .hl { color: var(--watch); }

.shelf__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 26px;
  align-items: start;
}
.shelf__card { padding: 12px; margin-top: var(--mt, 0); }
.shelf__card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
.shelf__card .cap {
  font-family: var(--f-hand);
  font-size: 13px;
  color: var(--soft);
  margin-top: 10px;
}
.shelf__more { min-height: 200px; }
.shelf__more .lead {
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 17px;
  color: var(--watch-deep);
  text-decoration: underline;
}
.shelf__more .sub {
  font-family: var(--f-hand);
  font-size: 13px;
  color: var(--muted);
}


/* ---------- camera roll ---------- */

.roll { --pl: 92px; --pr: 72px; padding-top: 84px; }
.roll .sec-head h2 { font-size: 24px; }

.roll__strip {
  display: flex;
  gap: 26px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.roll__card { padding: 10px 10px 12px; margin-top: var(--mt, 0); }

/* The photo keeps its own shape. Slot WIDTH is fixed — the varied widths are
   the desk look — but height follows the image's natural proportions, so a
   reel comes out tall and a square stays square. That variety is desk-native,
   and it is the standing rule: media is never cropped and never letterboxed.
   No max-height: Instagram's tallest format is 9:16, which at these widths
   (220px -> 391px) is a perfectly reasonable print on the desk. */
.roll__card img {
  width: var(--w, 220px);
  height: auto;
  max-width: 100%;
  display: block;
}

/* The empty well has no image to take a shape from, so it is the one thing here
   that keeps the board's fixed mount dimensions. */
.roll__card .well {
  width: var(--w, 220px);
  height: var(--h, 240px);
  max-width: 100%;
  display: block;
}
.roll__more { width: 200px; min-height: 230px; }
.roll__more .lead {
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 15px;
  color: var(--ico-instagram);
  text-decoration: underline;
}
.roll__cap {
  font-family: var(--f-hand);
  font-size: 12px;
  color: var(--soft);
  margin-top: 8px;
  max-width: var(--w, 220px);
}


/* ---------- shorts row ---------- */

.shorts { --pl: 84px; --pr: 96px; padding-top: 80px; }
.shorts .sec-head h2 { font-size: 24px; }

.shorts__grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 22px;
  align-items: start;
}
.shorts__card { padding: 9px; margin-top: var(--mt, 0); }
.shorts__card img {
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  display: block;
}
.shorts__card .cap {
  font-family: var(--f-hand);
  font-size: 12px;
  color: var(--soft);
  margin-top: 8px;
  text-align: center;
}
.shorts__more { min-height: 344px; }
.shorts__more .lead {
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 15px;
  color: var(--watch-deep);
  text-decoration: underline;
}
.shorts__more .sub {
  font-family: var(--f-hand);
  font-size: 12px;
  color: var(--muted);
}


/* ---------- the timeline: everything everywhere, lately ---------- */

.tl { --pl: 72px; --pr: 72px; padding-top: 84px; }
.tl .sec-head { margin-bottom: 30px; }

/* Three explicit rows of three. Grouping happens server-side in
   timeline_rows(); left-to-right wrapping was packing the real content mix into
   4/3/2. A row may under-fill — ragged rows are the desk look — but it can
   never overflow, because the row's widths are scaled to fit before render. */
.tl__strew { display: block; }

/* Fixed gap. Rows are packed to fill their line in timeline_rows(), so the
   spacing never has to stretch to cover leftover width. */
.tl__row {
  display: flex;
  gap: 28px;
  align-items: flex-start;
  margin-left: var(--indent, 0);
}
.tl__row + .tl__row { margin-top: 28px; }

/* Geometry is per-slot, set inline from lib/timeline.php. */
.tl-card {
  width: var(--w, 330px);
  margin-top: var(--mt, 0);
  margin-left: var(--ml, 0);
  padding: 24px;
}
.tl-card .tape { --tape-w: 64px; --tape-h: 18px; left: var(--tape-left, 24px); }

/* Platform labels sit inside a card, so they take the card face too. */
.tl-card .eyebrow { font-family: var(--f-body); }

.tl-card__head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 14px;
}
/* Karla, weight 700 — Karla ships no 600 in the face we load, and asking for
   600 would silently resolve to 700 anyway. */
.tl-card__title {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.45;
  margin: 0 0 12px;
}
/* Belt and braces behind the 300-character cap in post_excerpt().
   The cap is the real rule; this only catches the narrow cards. Twelve lines is
   chosen so it never fights the cap: 300 characters comes to about ten lines in
   the narrowest TEXT card (300px, ~33 chars a line), so a capped post is never
   clipped twice even if that estimate is off by a line or two. It still bounds
   the 236px Instagram card, which fits fewer characters per line.
   Clipping an inner block is safe: the focusable element is the card itself. */
/* Bluesky, Threads and Instagram all land here — prose, so Karla. It was
   already inheriting this from body; stated outright so it is a decision
   rather than an accident. */
.tl-card__text {
  font-family: var(--f-body);
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--body);
  margin: 0 0 12px;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 12;
  line-clamp: 12;
  overflow: hidden;
}
.tl-card__meta {
  font-family: var(--f-body);
  font-size: 13px;
  color: var(--muted-2);
}
.tl-card__meta .go { color: var(--link); }
.tl-card__meta .go[data-accent="watch"] { color: var(--watch); }
.tl-card__meta .go[data-accent="live"]  { color: var(--live); }

.tl-card img.media,
.tl-card .well.media {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  margin-bottom: 12px;
}
.tl-card .well.media--tall { aspect-ratio: auto; height: 200px; }

/* An Instagram photo keeps its own proportions, same rule as the camera roll.
   The 16:9 box above is for YouTube and Twitch, whose thumbnails are a known
   shape; an Instagram post can be anything from 1.91:1 to 9:16, so forcing it
   into that box was cropping the picture. Card WIDTH still comes from the
   type-width table — only the height is free. */
.tl-card img.media--photo {
  aspect-ratio: auto;
  height: auto;
  object-fit: fill;
}

/* compact portrait card for a Short */
.tl-card--short { padding: 9px 9px 11px; }
.tl-card--short .tl-card__head { gap: 7px; margin: 4px 0 8px 2px; }
.tl-card--short .eyebrow { font-size: 11px; }
.tl-card--short img.media {
  aspect-ratio: 9 / 16;
  margin-bottom: 0;
}
.tl-card--short .cap {
  font-family: var(--f-body);
  font-size: 12px;
  color: var(--soft);
  margin-top: 8px;
  text-align: center;
}
.tl-card--short .tl-card__meta {
  font-size: 11px;
  margin-top: 2px;
  text-align: center;
}

.tl__empty {
  font-family: var(--f-hand);
  font-size: 15px;
  color: var(--muted);
}


/* ---------- footer ---------- */

.foot {
  --pl: 72px; --pr: 72px;
  margin-top: 92px;
  padding-top: 36px;
  padding-bottom: 48px;
  border-top: 1px solid var(--rule);
  display: flex;
  /* baseline, not flex-end: the colophon is one short line and the ask beside
     it is four elements tall, so bottom-aligning left it stranded at the foot
     of the page under a column of empty space. Baseline sets it on the same
     line as "made it this far", and aligns the two type sizes on their
     baselines rather than merely on their box tops. */
  align-items: baseline;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
}
.foot__ask { display: flex; flex-direction: column; gap: 12px; }
.foot__line {
  font-family: var(--f-hand);
  font-size: 15px;
  color: var(--soft);
  /* Two lines, overhanging the signup row below it by about 70px.
     345px would align the sentence exactly with the add-me button, but this
     copy needs 400px before it will sit on two lines rather than three, so
     the alignment and the line count cannot both be had. Scott chose the
     line count. 410 rather than the 400 minimum leaves slack for the moment
     before Shantell Sans loads and a fallback face sets the text wider. */
  max-width: 410px;
}
.foot .signup input[type="email"] { width: 240px; font-size: 14px; padding: 5px 2px; }
.foot .signup button { font-size: 14px; padding: 9px 18px; }
.foot__sig {
  font-family: var(--f-hand);
  font-weight: 500;
  font-size: 18px;
  color: var(--ink);
}
.foot__colophon {
  font-family: var(--f-hand);
  font-size: 13px;
  color: var(--muted-2);
}


/* =========================================================================
   Responsive. Same document, same markup — the 1440 board is simply the
   widest case. Rotations survive; the indents do not.
   ========================================================================= */

@media (max-width: 1200px) {
  :root { --gutter: 40px; }
  .masthead, .hero, .hero-live, .note, .shelf, .roll, .shorts, .tl, .foot {
    --pl: var(--gutter);
    --pr: var(--gutter);
  }
  .hero { gap: 36px; }
  .note { gap: 36px; }
}

@media (max-width: 1080px) {
  .hero { flex-direction: column; align-items: stretch; }
  .hero__frame { flex: 1 1 auto; }
  .hero-live__row { flex-direction: column; }
  .hero-live__player { flex: 1 1 auto; }
  .room__chat { min-height: 420px; }

  .note { flex-direction: column-reverse; align-items: center; }
  .note__card { flex: 1 1 auto; max-width: none; }

  .shelf__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shelf__card { margin-top: 0; }

  .shorts__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .shorts__card { margin-top: 0; }
  .shorts__more { min-height: 0; padding: 28px 12px; }

  /* the collage becomes one readable column — keep the tilt, drop the indents.
     The three rows flatten: each becomes a plain block, so their cards stack
     into a single column in slot order. The timeline stays stacked on mobile
     on purpose — it is the reading feed, not a shelf. */
  .tl__row {
    display: block;
    margin-left: 0;
  }
  .tl__row + .tl__row { margin-top: 0; }
  .tl-card {
    width: 100%;
    margin: 0 0 24px;
  }
  .tl-card--short { width: 100%; max-width: 320px; }

  /* The desktop collage pulls a generous number of items so its rows can fill.
     In one column that would be an endless scroll, so the tail is dropped —
     this is a "lately" collage, not an archive. */
  .tl-card--extra { display: none; }
}

@media (max-width: 700px) {
  :root { --gutter: 20px; }

  .wordmark { font-size: 42px; }
  .masthead { padding-top: 18px; gap: 14px; }
  .masthead__right { padding-bottom: 0; gap: 16px; }
  .socials { gap: 18px; }

  .hero { padding-top: 22px; }
  .hero__frame { padding: 10px; }
  .hero__title { font-size: 25px; }
  .hero__play span { width: 60px; height: 60px; }

  .hero-live__player { padding: 10px; }
  .room__chat { min-height: 340px; }

  .note { padding-top: 56px; }
  .note__card { padding: 26px 22px; }
  .polaroid img { width: 100%; max-width: 250px; height: auto; aspect-ratio: 250 / 270; }

  .shelf, .roll, .tl { padding-top: 56px; }
  .shorts { padding-top: 52px; }

  .sec-head h2 { font-size: 21px; }
  .shelf .sec-head h2, .roll .sec-head h2, .shorts .sec-head h2, .tl .sec-head h2 { font-size: 21px; }
  .sec-head { gap: 10px; margin-bottom: 20px; }

  /* ---- the three shelves become one shared rail --------------------------
     All three behaved differently here: Still Single stacked, the camera roll
     wrapped, and shorts was a scroller with no affordance, so it just looked
     accidentally cut off. They are now the same component.

     --rail-card is sized so roughly a third of the next card always shows at
     the viewport edge. That peek is the affordance: it is what tells you the
     row scrolls, so it must never land on a near-clean cut.

     Solving for a 0.35-card peek, where V is the viewport, g the gutter and
     the flex-basis percentage resolves against the content box (V - 2g):
         n cards + n gaps + 0.35 card = V - g
       1-up ->  ~74% of the content box
       2-up ->  ~41%
     Those percentages hold within a point or two from 360px to 430px wide.

     The rail is full-bleed via negative margins, so cards run to the screen
     edge and the peek is not hidden behind the gutter. It scrolls inside its
     own box, so the page body never scrolls sideways.

     The timeline is deliberately NOT a rail — it is the reading feed. */
  .shelf__grid,
  .roll__strip,
  .shorts__grid {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--rail-gap, 16px);
    align-items: flex-start;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;      /* momentum on older iOS */
    scroll-snap-type: x proximity;
    scroll-padding-left: var(--gutter);
    /* full bleed, with room above for the tape and around for focus rings */
    margin-left: calc(var(--gutter) * -1);
    margin-right: calc(var(--gutter) * -1);
    padding: 12px var(--gutter) 14px;
    scrollbar-width: none;                  /* Firefox */
  }
  .shelf__grid::-webkit-scrollbar,
  .roll__strip::-webkit-scrollbar,
  .shorts__grid::-webkit-scrollbar { display: none; }

  .shelf__grid > *,
  .roll__strip > *,
  .shorts__grid > * {
    flex: 0 0 var(--rail-card, 74%);
    scroll-snap-align: start;
    margin-top: 0;                          /* the grid stagger, dropped */
    width: auto;
  }

  /* 16:9 with a caption — one at a time reads best */
  .shelf__grid { --rail-card: 74%; }
  .shelf__more { min-height: 0; padding: 26px 14px; }

  /* photos and portrait shorts are narrow enough to show two */
  .roll__strip   { --rail-card: 41%; }
  .shorts__grid  { --rail-card: 41%; }

  /* the wells sized themselves in px for the old wrapped strip */
  /* Natural height here too. The rail aligns tops (align-items: flex-start),
     so cards of different heights sit on a shared baseline at the top and the
     ragged bottom edge is the desk look, not a bug. */
  .roll__card img {
    width: 100%;
    height: auto;
  }
  .roll__card .well {
    width: 100%;
    height: var(--h-sm, 155px);
  }
  .roll__cap { max-width: none; }
  .roll__more { width: auto; min-height: var(--h-sm, 155px); padding: 22px 12px; }

  .shorts__more { min-height: 0; padding: 24px 10px; }

  .tl-card { padding: 20px; }
  .tl-card--short { max-width: none; }

  .foot { margin-top: 56px; padding-bottom: 36px; }
  .signup input[type="email"], .foot .signup input[type="email"] { width: 100%; }
  .signup { gap: 12px; }
}

/* The strewn indents are decoration; anyone who has asked for less motion or a
   simpler page still gets the tilt, but a printed page should sit straight. */
@media print {
  .card, .polaroid, .tl-card { transform: none; box-shadow: none; }
  .tape { display: none; }
}

/* ---------- 19 Sep 2026: masthead colour, footer, tip link ---------- */

/* Platform icons wear their platform colour at rest (--c is set inline per
   link by masthead()); every icon and the tip link go to ink on hover/focus. */
.socials a { color: var(--c, var(--muted)); transition: color .15s ease; }
.socials a:hover,
.socials a:focus-visible { color: var(--ink); }

/* The tip link: bag-with-heart glyph plus TIPS, in the wordmark's orange. */
.tip-link {
  color: var(--mark-h);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--f-hand);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-decoration: none;
  vertical-align: middle;
  transition: color .15s ease;
}
.tip-link:hover,
.tip-link:focus-visible { color: var(--ink); }

/* Footer: no second signup any more, so it stacks and centres. */
.foot { flex-direction: column; align-items: center; gap: 18px; }
.foot__ask { align-items: center; gap: 0; }
.foot__line { max-width: none; text-align: center; font-size: 14px; }
.foot__sig { font-size: 14px; font-weight: 500; color: var(--soft); margin-top: 2px; }
.foot__colophon { text-align: center; }

/* The email ask in the note card sits a blank line below the bio. */
.note__card .note__ask { margin-top: 1.6em; }

/* Skip link: the first focusable element in the masthead. Off-screen until a
   keyboard user tabs to it, then it drops into the top-left corner. Pointer
   users never see it. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 0 0 10px 0;
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus {
  left: 0;
  outline: 2px solid var(--mark-h);
  outline-offset: 2px;
}
