/* =========================================================
   ROBOOSHIES — core stylesheet

   Palette and type are locked in docs/BRAND_BOOK.md (variant C:
   Cornflower + Butter). Ink is the very dark navy she preferred
   over the book's #1B1D22 after the carousel test.

   Shape rule (one system, no exceptions):
     interactive things (buttons, chips, tags, inputs) = pill
     containers (cards, plates, panels)                 = 24px
     small insets (rows inside a card)                  = 14px
   One exception, documented: Booshi's speech bubble is its own object rather
   than a row inside a card, and takes 34px so it reads as inflated.

   Motion rule: one orchestrated moment on the home hero. Everything
   else only moves in answer to a person's action.

   1. Tokens   2. Base   3. Type   4. Layout   5. Components
   6. Header/footer   7. Home   8. Robot profile   9. Tools
   10. Motion   10b. Calendar   11. Responsive
   ========================================================= */

/* ---------- 1. Tokens ---------- */
:root {
  --cloud:   #FAF7F2;
  --sky:     #DCE6F7;
  --corn:    #6C8CD5;
  --butter:  #F2DFA4;
  --ring: var(--corn); /* hover ring and outlines: the Cornflower of a saved heart */
  --ink:     #161B2E;

  /* tints of the five, no new hues */
  --ink-80:  rgba(22, 27, 46, .80);
  --ink-62:  rgba(22, 27, 46, .62);
  --ink-45:  rgba(22, 27, 46, .45);
  --ink-14:  rgba(22, 27, 46, .14);
  --ink-07:  rgba(22, 27, 46, .07);
  --corn-12: rgba(108, 140, 213, .12);
  --corn-24: rgba(108, 140, 213, .24);
  --corn-40: rgba(108, 140, 213, .40);
  --corn-deep: #5B7BC6;
  --sky-deep:  #CBD8F0;
  --cloud-72: rgba(250, 247, 242, .72);
  --cloud-40: rgba(250, 247, 242, .40);
  --cloud-14: rgba(250, 247, 242, .14);

  --sans: "Inter", ui-sans-serif, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --display: "Syne", "Inter", ui-sans-serif, sans-serif;

  --shell: 1200px;
  --gutter: clamp(20px, 5vw, 56px);
  --section-y: clamp(64px, 9vw, 128px);
  --header-h: 68px;

  --r-card: 24px;
  --r-in: 14px;
  --r-pill: 999px;

  /* shadows tinted to the page hue, one scale */
  --lift-1: 0 1px 2px rgba(22, 27, 46, .04), 0 8px 24px -8px rgba(108, 140, 213, .22);
  --lift-2: 0 2px 4px rgba(22, 27, 46, .05), 0 24px 48px -16px rgba(108, 140, 213, .35);

  /* Clay: the soft inflated look, lit from above, at two depths.
     The soft pair goes on the tick and cross nubs that pass judgement and on
     the price. The full pair goes on Booshi alone: he is the one element allowed
     to behave like a character, and if everything were inflated the puff would
     stop meaning anything. No new hues. The light is a white highlight, the
     shade is Cornflower and Ink at low alpha. */
  /* a nub on a saturated fill takes a hard shade; one on a pale fill would go
     muddy, so it gets the softer pair */
  --clay-nub:  inset 0 2px 1.5px rgba(255, 255, 255, .70), inset 0 -3px 5px -1px rgba(22, 27, 46, .38);
  --clay-nub-soft: inset 0 2px 1px rgba(255, 255, 255, .90), inset 0 -2.5px 4px -1px rgba(22, 27, 46, .16);
  /* Booshi's depth. The avatar is an image, so it takes the drop only: an inset
     shadow would paint under the picture and never show. */
  --clay-lift: 0 5px 8px rgba(22, 27, 46, .07), 0 28px 44px -18px rgba(108, 140, 213, .68);
  --clay-face-full: inset 0 6px 4px rgba(255, 255, 255, 1), inset 0 -14px 22px -8px rgba(108, 140, 213, .58);
  --clay-sheen-full: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0) 72%);

  --ease: cubic-bezier(.22, .61, .36, 1);
  --spring: cubic-bezier(.34, 1.4, .64, 1);
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* The palette is light only, so say so: a browser in dark mode otherwise
   repaints native controls and scrollbars dark against a Cloud page. */
html {
  color-scheme: light;
  -webkit-text-size-adjust: 100%; scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-tap-highlight-color: rgba(108, 140, 213, .24);
}
body {
  margin: 0; background: var(--cloud); color: var(--ink);
  font-family: var(--sans); font-size: 17px; line-height: 1.6;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; touch-action: manipulation;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
.prose a, p a, .answer a { text-decoration: underline; text-decoration-color: var(--corn); text-underline-offset: .18em; text-decoration-thickness: 2px; }
.prose a:hover, p a:hover, .answer a:hover { text-decoration-color: var(--ink); }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p, dl, dd, figure { margin: 0; }
strong, b { font-weight: 600; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--corn); outline-offset: 3px; border-radius: 6px; }
.skip-link { position: absolute; left: 12px; top: -60px; z-index: 1000; background: var(--ink); color: var(--cloud); padding: 10px 16px; border-radius: var(--r-pill); font-weight: 500; }
.skip-link:focus { top: 12px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ---------- 3. Type ---------- */
.display, .h1, .h2 { font-family: var(--display); font-weight: 700; letter-spacing: -.01em; line-height: 1.04; text-wrap: balance; }
.h3 { font-weight: 600; letter-spacing: 0; text-wrap: balance; }
.display { font-size: clamp(36px, 5.2vw, 64px); }
.h1 { font-size: clamp(32px, 4.4vw, 52px); }
.h2 { font-size: clamp(28px, 3.2vw, 38px); line-height: 1.08; }
.h3 { font-size: clamp(20px, 2vw, 23px); line-height: 1.2; }
.lede { font-size: clamp(18px, 1.5vw, 20px); line-height: 1.5; color: var(--ink-80); max-width: 52ch; text-wrap: pretty; font-weight: 400; }
.muted { color: var(--ink-62); }
.small { font-size: 15px; }
.num { font-variant-numeric: tabular-nums; }
.prose { max-width: 66ch; }
.prose p + p { margin-top: 1em; }
.prose h2 { margin-top: 1.8em; margin-bottom: .35em; }
.prose > :first-child { margin-top: 0; }

/* ---------- 4. Layout ---------- */
.shell { width: min(var(--shell), 100% - 2 * var(--gutter)); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.section-tight { padding-block: clamp(40px, 6vw, 80px); }
.section-head { display: grid; gap: 12px; margin-bottom: clamp(24px, 4vw, 44px); max-width: 720px; }
.band-sky { background: var(--sky); }
.band-ink { background: var(--ink); color: var(--cloud); }
.band-ink .lede { color: var(--cloud-72); }
.grid { display: grid; gap: clamp(16px, 2.2vw, 24px); }
.stack { display: grid; gap: 12px; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.spread { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }

/* ---------- 5. Components ---------- */

/* Buttons. One primary per view. Cornflower on light, Cloud on dark. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px; padding: 0 26px; border-radius: var(--r-pill);
  font-weight: 500; font-size: 17px; line-height: 1; white-space: nowrap;
  transition: transform .16s var(--spring), background-color .16s var(--ease), box-shadow .16s var(--ease);
}
.btn:active { transform: translateY(1px) scale(.985); }
.btn svg { width: 20px; height: 20px; flex: none; }
.btn-primary { background: var(--corn); color: var(--ink); box-shadow: 0 8px 20px -8px var(--corn-40); }
.btn-primary:hover { background: var(--corn-deep); }
.btn-ink { background: var(--ink); color: var(--cloud); }
.btn-cloud { background: var(--cloud); color: var(--ink); }
.btn-quiet { background: var(--corn-12); color: var(--ink); }
.btn-quiet:hover { background: var(--corn-24); }
.band-ink .btn-quiet { background: var(--cloud-14); color: var(--cloud); }
.band-ink .btn-quiet:hover { background: rgba(250, 247, 242, .22); }
.btn-sm { min-height: 44px; padding: 0 18px; font-size: 15px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* Tags. Cornflower is the colour that says Robooshies. */
.tag { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: var(--r-pill); font-size: 14px; font-weight: 600; background: var(--corn); color: var(--ink); white-space: nowrap; }
.tag-soft { background: var(--corn-12); color: var(--ink); }
.tag-ink { background: var(--ink); color: var(--cloud); }
.band-ink .tag-soft { background: var(--cloud-14); color: var(--cloud); }

/* Butter: one warm spot per view. Price, age or a number. Never a background. */
.pill-butter { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border-radius: var(--r-pill); background: var(--butter); color: var(--ink); font-weight: 600; font-size: 15px; font-variant-numeric: tabular-nums; white-space: nowrap; box-shadow: 0 1px 2px rgba(22, 27, 46, .06), inset 0 2px 1px rgba(255, 255, 255, .60), inset 0 -3px 6px -2px rgba(22, 27, 46, .16); }
.pill-butter s { font-weight: 400; color: var(--ink-62); }
.pill-butter.lg { height: 52px; padding: 0 20px; font-family: var(--display); font-weight: 700; font-size: 28px; letter-spacing: -.01em; }
.pill-butter.lg s { font-family: var(--sans); font-weight: 400; font-size: 16px; }

/* Status: the word carries the meaning, the dot only echoes it. */
.status { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; font-size: 15px; }
.status::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--corn); }
.status[data-status="pre_order"]::before, .status[data-status="waitlist"]::before { background: var(--butter); box-shadow: inset 0 0 0 1.5px var(--ink-45); }
.status[data-status="region_limited"]::before { background: transparent; box-shadow: inset 0 0 0 2px var(--corn); }
.status[data-status="discontinued"]::before { background: var(--ink-14); }

/* Panels. Cards only where the thing really is a unit (a robot). */
.panel { background: var(--cloud); border-radius: var(--r-card); }
.panel-sky { background: var(--sky); border-radius: var(--r-card); }
.panel-pad { padding: clamp(20px, 2.6vw, 30px); }
.band-sky .panel { box-shadow: var(--lift-1); }

/* Robot plate. Until a photo exists the plate carries the robot's name set
   large: type as image, not a drawn placeholder. Fixed ratio so photos
   drop in later without a layout jump. */
.plate { position: relative; aspect-ratio: 4 / 3; border-radius: 20px; background: var(--sky); overflow: hidden; display: grid; place-items: center; }
/* Every robot photo is already cut out and centred on this exact background at
   4:3, so `cover` would only crop a robot's ears off in the plates that are not
   4:3. `contain` fits the whole product; the letterbox is the same colour as the
   plate, so there is nothing to see. */
.plate img { width: 100%; height: 100%; object-fit: contain; }
.plate .word { font-family: var(--display); font-weight: 700; font-size: clamp(28px, 3cqw + 12px, 36px); letter-spacing: -.01em; color: var(--corn); text-align: center; padding: 0 8%; line-height: 1.05; text-wrap: balance; }
.plate .kind { position: absolute; left: 14px; bottom: 12px; font-size: 13px; font-weight: 500; color: var(--ink-62); }
.plate-wrap { container-type: inline-size; }

/* Heart / save */
.heart { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--cloud); color: var(--ink); box-shadow: var(--lift-1); transition: transform .16s var(--spring), background-color .16s var(--ease), color .16s var(--ease); }
.heart svg { width: 22px; height: 22px; }
.heart svg path { fill: transparent; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; transition: fill .16s var(--ease); }
.heart:active { transform: scale(.9); }
.heart[aria-pressed="true"] { background: var(--corn); color: var(--cloud); }
.heart[aria-pressed="true"] svg path { fill: currentColor; }
.heart.pop { animation: heart-pop .4s var(--spring); }
@keyframes heart-pop { 0% { transform: scale(1); } 40% { transform: scale(1.22); } 100% { transform: scale(1); } }

/* Compare toggle */
.cmp-btn { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; border-radius: var(--r-pill); font-weight: 500; font-size: 15px; background: var(--corn-12); color: var(--ink); transition: background-color .16s var(--ease), color .16s var(--ease); }
.cmp-btn svg { width: 18px; height: 18px; }
.cmp-btn:hover { background: var(--corn-24); }
.cmp-btn[aria-pressed="true"] { background: var(--ink); color: var(--cloud); }

/* Facts (at a glance) */
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
.fact { display: grid; gap: 2px; padding: 12px 0; border-bottom: 1px solid var(--ink-14); }
.fact dt { font-size: 14px; font-weight: 500; color: var(--ink-62); }
.fact dd { font-weight: 600; font-size: 16.5px; line-height: 1.35; }
.fact dd small { display: block; font-weight: 400; color: var(--ink-62); font-size: 13.5px; margin-top: 2px; }

/* Check / cross lists */
.list-check li, .list-cross li { position: relative; padding-left: 38px; margin-bottom: 12px; line-height: 1.5; font-weight: 400; }
.list-check li::before, .list-cross li::before { content: ""; position: absolute; left: 0; top: 1px; width: 25px; height: 25px; border-radius: 50%; background-repeat: no-repeat; background-position: center; background-size: 13px; box-shadow: var(--clay-nub); }
.list-check li::before { background-color: var(--corn); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FAF7F2' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E"); }
.list-cross li::before { box-shadow: var(--clay-nub-soft); background-color: var(--ink-07); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161B2E' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E"); }

/* Booshi comment bubble. The mascot is small and in a corner, commenting. */
.booshi-says { display: grid; grid-template-columns: 56px 1fr; gap: 14px; align-items: start; }
.booshi-says img { width: 56px; height: 56px; border-radius: 50%; background: var(--sky); box-shadow: var(--clay-lift); }
/* A speech bubble is its own object, not a row inside a card, so it takes a
   rounder corner than the 14px inset rule. */
.booshi-says .bubble { position: relative; background-color: var(--cloud); background-image: var(--clay-sheen-full); border-radius: 34px; padding: 20px 24px; font-weight: 500; line-height: 1.5; box-shadow: var(--clay-lift), var(--clay-face-full); }
.panel .booshi-says .bubble { background-color: var(--sky); }
.booshi-says .bubble::before { content: ""; position: absolute; left: -8px; top: 24px; width: 18px; height: 18px; background-color: inherit; background-image: none; transform: rotate(45deg); border-radius: 5px; }
.booshi-says .who { display: block; font-size: 14px; font-weight: 500; color: var(--corn); margin-bottom: 2px; }

/* Forms. Label above, error below, never placeholder-as-label. */
.field { display: grid; gap: 8px; }
.field label { font-weight: 500; font-size: 15px; }
.input { width: 100%; min-height: 52px; padding: 0 18px; border-radius: var(--r-pill); border: 2px solid var(--ink-14); background: var(--cloud); font-size: 17px; font-weight: 400; transition: border-color .16s var(--ease), box-shadow .16s var(--ease); }
.input::placeholder { color: var(--ink-45); }
.input:focus { outline: none; border-color: var(--corn); box-shadow: 0 0 0 4px var(--corn-12); }
.input[aria-invalid="true"] { border-color: var(--ink); }
.field-error { font-size: 14px; font-weight: 500; min-height: 1.2em; }
.form-note { font-size: 14px; color: var(--ink-62); font-weight: 400; }
.notice { border-radius: var(--r-in); padding: 14px 18px; background: var(--corn-12); font-weight: 400; font-size: 15px; line-height: 1.5; }
.band-ink .notice { background: var(--cloud-14); }

/* FAQ */
.faq details { border-top: 1px solid var(--ink-14); }
.faq details:last-child { border-bottom: 1px solid var(--ink-14); }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 18px 0; font-weight: 600; font-size: 18px; line-height: 1.3; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--corn-12) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161B2E' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E") no-repeat center / 12px; transition: transform .2s var(--ease); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .answer { padding: 0 0 20px; color: var(--ink-80); max-width: 66ch; line-height: 1.6; font-weight: 400; }

/* Toast */
.toast { position: fixed; left: 50%; bottom: 96px; transform: translate(-50%, 20px); background: var(--ink); color: var(--cloud); padding: 12px 18px; border-radius: var(--r-pill); font-weight: 500; font-size: 15px; box-shadow: var(--lift-2); opacity: 0; pointer-events: none; transition: opacity .2s var(--ease), transform .25s var(--spring); z-index: 900; }
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast a { color: var(--butter); text-decoration: underline; pointer-events: auto; }

/* ---------- 6. Header & footer ---------- */
.site-header { position: sticky; top: 0; z-index: 100; background: rgba(250, 247, 242, .88); backdrop-filter: saturate(140%) blur(12px); -webkit-backdrop-filter: saturate(140%) blur(12px); border-bottom: 1px solid transparent; transition: border-color .2s var(--ease); }
.site-header.is-stuck { border-color: var(--ink-07); }
.header-bar { display: flex; align-items: center; justify-content: space-between; gap: 20px; height: var(--header-h); }
.wordmark { display: inline-flex; align-items: center; }
.wordmark img { height: 28px; width: auto; }
.site-footer .wordmark img { height: 32px; }
.site-nav ul { display: flex; align-items: center; gap: 2px; }
.site-nav a { display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: var(--r-pill); font-weight: 500; font-size: 15.5px; color: var(--ink-80); transition: background-color .16s var(--ease), color .16s var(--ease); }
.site-nav a:hover, .site-nav a[aria-current="page"] { background: var(--corn-12); color: var(--ink); }
.site-nav a { white-space: nowrap; }
/* Just above the menu button, six links fit only a little closer together. */
@media (min-width: 901px) and (max-width: 1060px) { .site-nav a { padding: 0 9px; font-size: 15px; } }
.nav-my .count { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; margin-left: 6px; border-radius: var(--r-pill); background: var(--corn); color: var(--ink); font-size: 12.5px; font-weight: 600; }
.nav-my .count[hidden] { display: none; }
.nav-toggle { display: none; align-items: center; gap: 8px; height: 44px; padding: 0 16px 0 12px; border-radius: var(--r-pill); background: var(--corn-12); color: var(--ink); font-family: var(--sans); font-weight: 500; font-size: 15.5px; }
.nav-toggle svg { width: 22px; height: 22px; }
.nav-toggle[aria-expanded="true"] { background: var(--ink); color: var(--cloud); }

.site-footer { padding: clamp(48px, 7vw, 88px) 0 36px; background: var(--sky); }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 32px; margin-bottom: 40px; }
.footer-grid h3 { font-size: 15px; font-weight: 500; color: var(--ink-62); margin-bottom: 14px; }
.footer-grid li { margin-bottom: 8px; font-weight: 500; }
.footer-grid li a:hover { text-decoration: underline; text-decoration-color: var(--corn); text-underline-offset: .18em; }
.footer-about { max-width: 40ch; color: var(--ink-80); font-weight: 400; margin-top: 12px; }
.footer-legal { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; padding-top: 24px; border-top: 1px solid var(--ink-14); font-size: 14px; color: var(--ink-62); font-weight: 400; }

/* ---------- 7. Home ---------- */
.hero { position: relative; overflow: hidden; padding-block: clamp(28px, 5vw, 64px) clamp(40px, 6vw, 80px); }
.hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; align-items: center; gap: clamp(24px, 5vw, 64px); }
.hero-copy { display: grid; gap: 20px; }
.hero-copy .display { max-width: 11ch; }
.hero-copy > .tag { justify-self: start; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 4px; }
.hero-note { font-size: 15px; color: var(--ink-62); font-weight: 400; }
/* The paid book, on the first screen: a small card, not a third button. */
.hero-promo { justify-self: start; display: inline-flex; align-items: center; gap: 14px; max-width: 100%; margin-top: 6px; padding: 10px 18px 10px 10px; border-radius: 18px; background: var(--sky); color: var(--ink); box-shadow: var(--lift-1); transition: box-shadow .2s var(--ease), transform .2s var(--ease); }
.hero-promo img { width: 46px; height: auto; border-radius: 5px; box-shadow: 0 2px 6px rgba(22, 27, 46, .18); transform: rotate(-4deg); flex: none; }
.hero-promo-text { display: grid; gap: 2px; line-height: 1.3; }
.hero-promo-text b { font-weight: 700; font-size: 16px; }
.hero-promo-text span { font-size: 14.5px; color: var(--ink-80); }
.hero-promo-price { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.hero-promo-price .pb-now { font-size: 26px; }
.hero-promo-price .pb-was { font-size: 16px; }
.hero-promo > svg { width: 20px; height: 20px; flex: none; }
@media (hover: hover) { .hero-promo:hover { box-shadow: 0 0 0 2px var(--ring), var(--lift-2); transform: translateY(-2px); } }
@media (max-width: 520px) {
  .hero-promo { display: grid; grid-template-columns: 46px 1fr; column-gap: 14px; row-gap: 4px; padding-right: 14px; }
  .hero-promo img { grid-row: span 2; align-self: center; }
  .hero-promo > svg { display: none; }
}
.hero-note a { text-decoration: underline; text-decoration-color: var(--corn); text-underline-offset: .18em; text-decoration-thickness: 2px; }
.hero-art { position: relative; display: grid; place-items: center; }
.hero-art .disc { position: absolute; inset: 4% 6%; border-radius: 50%; background: var(--sky); }
.hero-art img { position: relative; width: min(100%, 440px); filter: drop-shadow(0 30px 40px rgba(22, 27, 46, .16)); }
.hero-art .callout { position: absolute; right: 0; top: 12%; background: var(--cloud); border-radius: var(--r-in); padding: 12px 16px; box-shadow: var(--lift-2); font-weight: 600; font-size: 15px; max-width: 210px; line-height: 1.35; }
.hero-art .callout .who { display: block; font-size: 14px; color: var(--corn); margin-bottom: 2px; }

/* Facts strip under the hero: the trust line lives here, not in the hero. */
.strip { display: flex; flex-wrap: wrap; gap: 10px 32px; padding: 18px 0; border-top: 1px solid var(--ink-14); border-bottom: 1px solid var(--ink-14); font-weight: 500; font-size: 15.5px; }
.strip li { display: inline-flex; align-items: center; gap: 10px; }
.strip li svg { width: 20px; height: 20px; color: var(--corn); }

/* Kinds: a single row of six, chips rather than cards */
.kinds { display: flex; flex-wrap: wrap; gap: 10px; }
.kinds a { display: inline-flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 20px 0 14px; border-radius: var(--r-pill); background: var(--cloud); box-shadow: inset 0 0 0 2px var(--ink-14); font-weight: 600; font-size: 16px; transition: box-shadow .16s var(--ease), background-color .16s var(--ease); }
.kinds a:hover { box-shadow: inset 0 0 0 2px var(--ink); }
.kinds a .n { display: inline-grid; place-items: center; min-width: 28px; height: 28px; padding: 0 8px; border-radius: var(--r-pill); background: var(--corn-12); font-size: 13.5px; font-weight: 600; }

/* Robot cards. The robots are the heroes; this is the one place cards belong. */
.robots-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.robot-card { position: relative; display: grid; grid-template-rows: auto 1fr; gap: 14px; padding: 12px 12px 20px; background: var(--cloud); border-radius: var(--r-card); box-shadow: var(--lift-1); }
.band-sky .robot-card { box-shadow: none; }
.robot-card .heart { position: absolute; top: 22px; right: 22px; z-index: 2; }
.robot-card .body { display: grid; gap: 8px; padding: 0 8px; align-content: start; }
.robot-card .name { font-size: 22px; font-weight: 600; letter-spacing: -.015em; line-height: 1.12; }
.robot-card .name a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 1; }
.robot-card .maker { font-size: 14.5px; font-weight: 500; color: var(--ink-62); }
.robot-card .line { color: var(--ink-80); font-weight: 400; font-size: 15.5px; line-height: 1.45; }
.robot-card .foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.robot-card .cmp-btn { position: relative; z-index: 2; }
.robot-card .meta { display: flex; flex-wrap: wrap; gap: 6px; }
.robot-card .meta .tag { height: 28px; font-size: 13.5px; }

/* Compare teaser: a real, working mini compare, not a picture of one */
.teaser { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(24px, 5vw, 64px); align-items: center; }
.teaser .copy { display: grid; gap: 18px; }
/* A four-column table cannot shrink below its own content, so on a phone it
   dragged the whole page sideways. Let it scroll inside its own box instead. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--r-card); }
.table-scroll .mini-compare { min-width: 340px; }
.mini-compare { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--cloud); border-radius: var(--r-card); overflow: hidden; box-shadow: var(--lift-1); }
.mini-compare th, .mini-compare td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--ink-14); font-size: 15.5px; font-weight: 600; }
.mini-compare thead th { background: var(--ink); color: var(--cloud); font-weight: 600; font-size: 16px; border-bottom: 0; }
.mini-compare thead th:first-child { background: var(--cloud); }
.mini-compare tbody th { color: var(--ink-62); font-weight: 500; width: 34%; }
.mini-compare tbody tr:last-child th, .mini-compare tbody tr:last-child td { border-bottom: 0; }
.mini-compare .pill-butter { height: 28px; font-size: 14px; padding: 0 10px; }


/* CTA band */
.cta-band { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 24px 48px; }
.cta-band .h2 { max-width: 18ch; }
.cta-band .lede { margin-top: 10px; }

/* ---------- 8. Robot profile ---------- */
.crumbs { display: flex; flex-wrap: wrap; gap: 8px; font-size: 14.5px; font-weight: 500; color: var(--ink-62); padding-top: 20px; }
.crumbs a:hover { color: var(--ink); }
.crumbs li + li::before { content: "/"; margin-right: 8px; color: var(--ink-45); }
.profile-head { display: grid; gap: 14px; padding-block: clamp(20px, 3vw, 36px) clamp(24px, 3vw, 40px); max-width: 800px; }
.profile-head .maker { font-size: 17px; font-weight: 500; color: var(--ink-62); }
.profile-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(20px, 3vw, 40px); align-items: start; }
.profile-media .plate { aspect-ratio: 4 / 3.2; }
.profile-media .plate .word { font-size: clamp(36px, 6vw, 64px); }
.profile-media figcaption { margin-top: 10px; font-size: 14px; color: var(--ink-62); font-weight: 400; }
.glance { position: sticky; top: calc(var(--header-h) + 16px); display: grid; gap: 18px; }
.glance .price-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.glance .actions { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; }
/* The buy button carries the maker's name and does not wrap, so on a phone the
   three-across row sets a floor of about 410px and pushes the whole page wider
   than the screen. Give it its own row instead. */
@media (max-width: 560px) {
  .glance .actions { grid-template-columns: 1fr auto; }
  .glance .actions > .btn:first-child { grid-column: 1 / -1; }
}
.glance .btn { width: 100%; }
.glance .fine { font-size: 14px; color: var(--ink-62); font-weight: 400; line-height: 1.45; }
.profile-body { display: grid; gap: clamp(36px, 5vw, 64px); padding-block: clamp(36px, 5vw, 72px); }
.profile-body .block { display: grid; gap: 16px; align-content: start; }
.profile-body .block-2 { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 4vw, 48px); }
.profile-body .h2 { max-width: 20ch; }
.spec-table { width: 100%; border-collapse: collapse; font-size: 16px; }
.spec-table th, .spec-table td { text-align: left; padding: 12px 0; border-bottom: 1px solid var(--ink-14); vertical-align: top; }
.spec-table th { width: 42%; font-weight: 500; color: var(--ink-62); padding-right: 16px; }
.spec-table td { font-weight: 500; }
.similar { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.similar .robot-card .name { font-size: 19px; }
.last-checked { display: inline-flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 500; color: var(--ink-62); }
.last-checked svg { width: 16px; height: 16px; color: var(--corn); }

/* ---------- 9. Tools: catalogue, compare, my robots ---------- */
.page-head { padding-block: clamp(32px, 5vw, 64px) clamp(20px, 3vw, 36px); display: grid; gap: 12px; max-width: 800px; }
.filters { display: flex; flex-wrap: wrap; gap: 8px; padding-bottom: 24px; }
.chip { display: inline-flex; align-items: center; gap: 8px; min-height: 42px; padding: 0 16px; border-radius: var(--r-pill); background: var(--cloud); box-shadow: inset 0 0 0 2px var(--ink-14); font-weight: 600; font-size: 15px; transition: background-color .16s var(--ease), box-shadow .16s var(--ease), color .16s var(--ease); }
.chip:hover { box-shadow: inset 0 0 0 2px var(--ink); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--cloud); box-shadow: none; }
.chip .n { font-size: 13px; color: var(--ink-62); }
.chip[aria-pressed="true"] .n { color: var(--cloud-72); }
.results-line { font-size: 15px; font-weight: 500; color: var(--ink-62); padding-bottom: 20px; }
.empty { padding: 40px 24px; text-align: center; border-radius: var(--r-card); background: var(--sky); font-weight: 500; display: grid; gap: 12px; justify-items: center; }
.empty img { width: 120px; }

/* Compare tray */
.tray { position: fixed; left: 50%; bottom: 20px; transform: translate(-50%, 130%); z-index: 800; display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 18px; background: var(--ink); color: var(--cloud); border-radius: var(--r-pill); box-shadow: var(--lift-2); transition: transform .3s var(--spring); max-width: calc(100% - 32px); }
.tray.show { transform: translate(-50%, 0); }
.tray .names { font-weight: 500; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 42vw; }
.tray .names span { color: var(--butter); }
.tray .btn { min-height: 44px; }
.tray .clear { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; color: var(--cloud-72); }
.tray .clear:hover { color: var(--cloud); background: var(--cloud-14); }
.tray .clear svg { width: 20px; height: 20px; }

/* Compare page */
.picker { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding-bottom: 28px; }
.picker label { display: grid; gap: 6px; font-weight: 500; font-size: 15px; }
.picker select { width: 100%; min-height: 52px; padding: 0 44px 0 18px; border-radius: var(--r-pill); border: 2px solid var(--ink-14); background: var(--cloud) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161B2E' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 16px center / 18px; appearance: none; font-weight: 500; }
.picker select:focus { outline: none; border-color: var(--corn); box-shadow: 0 0 0 4px var(--corn-12); }
.compare-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--r-card); background: var(--cloud); box-shadow: var(--lift-1); }
.compare { width: 100%; min-width: 720px; border-collapse: separate; border-spacing: 0; table-layout: fixed; }
.compare th, .compare td { padding: 14px 18px; border-bottom: 1px solid var(--ink-14); vertical-align: top; text-align: left; }
.compare thead th { position: sticky; top: 0; background: var(--cloud); z-index: 1; padding-top: 20px; }
.compare thead th:first-child { width: 180px; }
.compare tbody th { font-size: 15px; font-weight: 500; color: var(--ink-62); background: var(--cloud); position: sticky; left: 0; }
.compare tbody td { font-weight: 600; font-size: 16px; }
.compare tbody td .sub { display: block; font-size: 13.5px; font-weight: 400; color: var(--ink-62); margin-top: 2px; }
.compare tbody tr:nth-child(even) td, .compare tbody tr:nth-child(even) th { background: rgba(220, 230, 247, .35); }
.compare .head-cell { display: grid; gap: 10px; }
.compare .head-cell .plate { aspect-ratio: 16 / 10; border-radius: var(--r-in); }
.compare .head-cell .plate .word { font-family: var(--sans); font-weight: 600; font-size: clamp(18px, 2vw, 24px); }
.compare .head-cell .name { font-size: 18px; font-weight: 600; line-height: 1.15; }
.compare .head-cell .maker { font-size: 13.5px; color: var(--ink-62); font-weight: 500; }
.compare .yes::before, .compare .no::before { content: ""; display: inline-block; width: 20px; height: 20px; border-radius: 50%; vertical-align: -4px; margin-right: 8px; background-repeat: no-repeat; background-position: center; background-size: 11px; box-shadow: var(--clay-nub); }
.compare .yes::before { background-color: var(--corn); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FAF7F2' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E"); }
.compare .no { color: var(--ink-45); }
.compare .no::before { box-shadow: var(--clay-nub-soft); background-color: var(--ink-07); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161B2E' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E"); }

.rank { position: absolute; left: 22px; top: 22px; z-index: 2; }

/* The free report. The cover is the hero: it is the thing being handed over,
   so it is shown rather than described. */
.guide-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: clamp(28px, 5vw, 64px); align-items: start; padding-top: clamp(16px, 2vw, 28px); }
.guide-copy { display: grid; gap: 16px; align-content: start; max-width: 58ch; }
.guide-copy .h1 { margin-bottom: 2px; }
.guide-copy .h3 { margin-top: 12px; }
.guide-copy .list-check li strong { font-weight: 600; }
.guide-get { display: grid; gap: 12px; justify-items: start; margin-top: 12px; padding: clamp(20px, 2.6vw, 26px); background: var(--sky); border-radius: var(--r-card); width: 100%; }
.guide-get .field { width: min(360px, 100%); }
.guide-get .form-note { margin-top: 2px; }
.guide-cover { margin: 0; display: grid; gap: 10px; justify-items: center; }
.guide-cover img { width: 100%; height: auto; border-radius: var(--r-in); box-shadow: var(--lift-2); }
.guide-cover figcaption { font-size: 14px; color: var(--ink-62); }

/* Where to go from here: the last block on every robot page. Three parallel
   routes share one Sky panel, split by hairlines rather than boxed as cards;
   the money offer is a different kind of thing, so it sits apart in Ink. */
.next-steps { display: grid; gap: clamp(14px, 2vw, 20px); margin-top: clamp(44px, 6vw, 72px); }
.routes { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); background: var(--sky); border-radius: var(--r-card); }
.route { display: grid; gap: 8px; align-content: start; padding: clamp(20px, 2.6vw, 30px); }
.route + .route { border-left: 1px solid rgba(22, 27, 46, .10); }
.route .ask, .pay .ask { font-size: 15px; font-weight: 500; }
.route .ask { color: var(--ink-80); }
.route .go { display: inline-flex; align-items: flex-start; gap: 8px; font-weight: 600; font-size: 18.5px; line-height: 1.32; color: var(--ink); text-wrap: pretty; }
.route .go + .go { margin-top: 6px; }
.route .go svg { width: 18px; height: 18px; flex: none; margin-top: 4px; color: var(--corn-deep); transition: transform .16s var(--ease); }
.route .go:hover { color: var(--corn-deep); }
.route .go:hover svg { transform: translateX(3px); }
.pay { display: grid; grid-template-columns: 1fr auto; gap: 20px 36px; align-items: end; background: var(--ink); color: var(--cloud); border-radius: var(--r-card); padding: clamp(24px, 3.4vw, 40px); }
.pay-copy { display: grid; gap: 8px; }
.pay .ask { color: var(--cloud-72); }
/* Her words are "MAKE IT PAY". Written in sentence case and set in capitals
   here, so a screen reader says the phrase instead of spelling it out. */
.pay-title { text-transform: uppercase; letter-spacing: .02em; }
.pay p { color: var(--cloud-72); max-width: 46ch; font-weight: 400; }
.pay .pb-price { margin-top: 6px; color: var(--cloud); }
.pay .pb-was { color: var(--cloud-72); }
.pay .tag-save { background: transparent; color: var(--cloud); }

/* Articles. A reading column, not a dashboard: one measure, generous leading,
   and only the pieces that carry meaning get a treatment of their own. */
.article { padding-top: 8px; }
.article-head { display: grid; gap: 14px; justify-items: start; margin-bottom: clamp(20px, 3vw, 30px); }
.article-body { max-width: 68ch; font-size: 18px; line-height: 1.68; }
.article-body > * + * { margin-top: 1.05em; }
.article-body h2 { font-family: var(--display); font-weight: 700; font-size: clamp(24px, 2.6vw, 30px); line-height: 1.14; letter-spacing: -.01em; margin-top: 1.9em; text-wrap: balance; }
.article-body > p:first-child { font-size: clamp(19px, 1.6vw, 21px); line-height: 1.55; color: var(--ink-80); }
.article-body strong { font-weight: 600; }
.article-body hr { border: 0; border-top: 1px solid var(--ink-14); margin-top: 2.2em; }
.article-body .byline { font-size: 15px; color: var(--ink-62); }
.article-body .faq-q { font-weight: 600; margin-top: 1.6em; }
.article-body .faq-q + p { margin-top: .3em; }
.article-body .author-box { background: var(--sky); border-radius: var(--r-card); padding: 20px 24px; font-size: 16px; line-height: 1.55; margin-top: 2em; }
.article-body .bullets li, .article-body .numbered li { margin-bottom: .55em; }
.article-body .bullets li { position: relative; padding-left: 22px; }
.article-body .bullets li::before { content: ""; position: absolute; left: 2px; top: .62em; width: 7px; height: 7px; border-radius: 50%; background: var(--corn); }
.article-body .numbered { counter-reset: n; }
.article-body .numbered li { position: relative; padding-left: 30px; counter-increment: n; }
.article-body .numbered li::before { content: counter(n) "."; position: absolute; left: 0; top: 0; font-weight: 600; color: var(--corn); font-variant-numeric: tabular-nums; }
.article-table { width: 100%; min-width: 460px; border-collapse: separate; border-spacing: 0; background: var(--cloud); box-shadow: var(--lift-1); font-size: 16px; }
.article-table th, .article-table td { padding: 13px 16px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--ink-14); }
.article-table thead th { background: var(--ink); color: var(--cloud); font-weight: 600; border-bottom: 0; }
.article-table tbody th { font-weight: 500; color: var(--ink-62); }
.article-table tbody tr:last-child th, .article-table tbody tr:last-child td { border-bottom: 0; }
/* Article cards carry their picture on top; a card without one keeps the plain
   text layout, so a missing picture never leaves a hole. */
.article-list { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }
.article-list a { display: grid; gap: 6px; align-content: start; padding: 18px 22px; border-radius: var(--r-in); background: var(--cloud); box-shadow: var(--lift-1); height: 100%; }
.article-list a:has(.thumb) { padding: 0 0 20px; overflow: hidden; }
.article-list a:has(.thumb) > span { padding: 0 20px; }
.article-list .thumb { width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; margin-bottom: 8px; }
.article-hero { margin: 0 0 clamp(22px, 3vw, 34px); }
.article-hero img { width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; border-radius: var(--r-card); box-shadow: var(--lift-1); }
.article-list .title { font-weight: 600; font-size: 18px; line-height: 1.3; }
.article-list .blurb { font-size: 15px; color: var(--ink-62); font-weight: 400; line-height: 1.45; }
.article-list a:hover .title { color: var(--corn); }

/* Head to head: /compare/<a>-vs-<b>/ */
.vs-block { display: grid; gap: 16px; align-content: start; margin-top: clamp(36px, 5vw, 56px); }
.versus { display: grid; grid-template-columns: 1fr auto 1fr; gap: clamp(16px, 2.4vw, 28px); align-items: start; margin-top: 8px; }
.vs-mark { align-self: center; font-family: var(--display); font-weight: 700; font-size: clamp(20px, 2.4vw, 30px); color: var(--corn); }
.vs-card { background: var(--cloud); border-radius: var(--r-card); box-shadow: var(--lift-1); padding: 16px; display: grid; gap: 14px; align-content: start; }
.vs-figure { margin: 0; }
.vs-figure figcaption { margin-top: 10px; font-size: 13.5px; line-height: 1.45; color: var(--ink-62); font-weight: 400; }
.vs-body { display: grid; gap: 6px; }
.vs-body .h3 { margin: 0; }
.vs-body .maker { font-size: 14px; color: var(--ink-62); font-weight: 500; }
.vs-body .line { font-weight: 400; line-height: 1.5; }
.vs-body .foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 6px; }
.picks { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(16px, 2.4vw, 28px); }
.pick { background: var(--cloud); border-radius: var(--r-card); box-shadow: var(--lift-1); padding: clamp(18px, 2.4vw, 26px); display: grid; gap: 12px; align-content: start; }
.pick .h3 { margin: 0; }
.pick p { font-weight: 400; line-height: 1.55; }
.pick ul { margin: 0; }
.vs-note { max-width: 68ch; }
/* Two columns instead of three, so the table does not force a scroll it does
   not need. Below that width the wrapper scrolls, the page never does. */
.compare.duo { min-width: 520px; }
.third-band { display: grid; grid-template-columns: 1fr minmax(240px, 340px); gap: clamp(18px, 3vw, 36px); align-items: center; background: var(--sky); border-radius: var(--r-card); padding: clamp(20px, 3vw, 32px); }
.third-pick { display: grid; gap: 8px; font-weight: 500; font-size: 15px; }
.third-pick select { width: 100%; min-height: 52px; padding: 0 44px 0 18px; border-radius: var(--r-pill); border: 2px solid var(--ink-14); background: var(--cloud) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161B2E' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 16px center / 18px; appearance: none; font-weight: 500; }
.third-pick select:focus { outline: none; border-color: var(--corn); box-shadow: 0 0 0 4px var(--corn-12); }
.vs-links { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; margin: 0; }
.vs-links li { list-style: none; }
.vs-links a { display: block; padding: 14px 18px; border-radius: var(--r-in); background: var(--cloud); box-shadow: var(--lift-1); font-weight: 600; }
.vs-links a:hover { color: var(--corn); }

/* Save-list panel */
.save-panel { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 4vw, 48px); align-items: center; }
.save-panel form { display: grid; gap: 14px; }
.save-panel .inline { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: end; }

/* ---------- 10. Motion: one moment on the home hero ---------- */
.js .hero-copy > * { opacity: 0; transform: translateY(14px); animation: rise .6s var(--ease) forwards; }
.js .hero-copy > :nth-child(2) { animation-delay: .08s; }
.js .hero-copy > :nth-child(3) { animation-delay: .16s; }
.js .hero-copy > :nth-child(4) { animation-delay: .24s; }
.js .hero-art img { opacity: 0; transform: translateY(24px) scale(.96); animation: land .8s var(--spring) .1s forwards; }
.js .hero-art .callout { opacity: 0; transform: translateY(8px); animation: rise .5s var(--ease) .7s forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }
@keyframes land { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto; }
  .js .hero-copy > *, .js .hero-art img, .js .hero-art .callout { opacity: 1; transform: none; }
}

/* ---------- 10b. Calendar ----------
   Built from the site's own parts: the widget and every event sit in .panel,
   so they inherit the 24px container radius. Day cells are interactive, so by
   the shape rule they are pills, which here means circles. Butter stays out of
   this page entirely: the rule is one warm spot per view and never a
   background, and a grid of warm squares would break both. */
.cal-hero { padding-block: clamp(24px, 4vw, 56px) clamp(32px, 5vw, 64px); }
.cal-hero-grid {
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.cal-hero-copy { display: grid; gap: 18px; align-content: start; }
.cal-hero-copy > .tag { justify-self: start; }
.cal-hero-copy .display { max-width: 15ch; }
.cal-hero-copy .lede { max-width: 46ch; }

@media (min-width: 960px) {
  .cal-hero-grid { grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); }
}

/* The month grid */
.cal-widget { box-shadow: var(--lift-1); }
.cw-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding-bottom: 14px; border-bottom: 1px solid var(--ink-14);
}
.cw-title { font-weight: 600; font-size: 17px; }
.cw-nav {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 20px; line-height: 1; color: var(--ink);
  background: var(--corn-12);
  transition: background-color .16s var(--ease);
}
.cw-nav:hover:not(:disabled) { background: var(--corn-24); }
.cw-nav:disabled { opacity: .4; cursor: default; }

.cw-grid { width: 100%; border-collapse: collapse; table-layout: fixed; margin-top: 14px; }
.cw-grid th { padding: 8px 0 10px; font-size: 13px; font-weight: 500; color: var(--ink-62); }
.cw-grid th abbr { text-decoration: none; }
.cw-d, .cw-pad { height: 40px; text-align: center; padding: 2px; }
.cw-d { font-size: 15px; font-weight: 500; color: var(--ink-62); font-variant-numeric: tabular-nums; }
.cw-d--on a {
  display: grid; place-items: center;
  width: 100%; height: 100%; min-height: 36px;
  border-radius: var(--r-pill);
  /* Ink on cornflower is 5.2:1. Cloud on cornflower is 3.1:1 and would fail. */
  background: var(--corn); color: var(--ink);
  font-weight: 600;
  transition: transform .16s var(--spring), background-color .16s var(--ease);
}
.cw-d--on a:hover { background: var(--corn-deep); transform: scale(1.06); }

.cw-agenda { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--ink-14); display: grid; gap: 2px; }
.cw-agenda a { display: block; padding: 7px 0; font-weight: 500; font-size: 15px; line-height: 1.4; }
.cw-agenda a:hover { text-decoration: underline; text-decoration-color: var(--corn); text-underline-offset: .18em; }
.cw-ag-date { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.cw-agenda a { color: var(--ink-80); }
.cw-foot { margin-top: 14px; font-size: 13.5px; color: var(--ink-62); font-weight: 400; }

/* Events */
.cal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: clamp(14px, 2vw, 22px);
}
.cal-ev { display: flex; flex-direction: column; gap: 8px; box-shadow: var(--lift-1); }
.band-sky .cal-ev { box-shadow: none; }
.cal-ev-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cal-ev-date { font-weight: 600; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
.cal-ev-name { font-size: 21px; font-weight: 600; letter-spacing: -.015em; line-height: 1.15; }
.cal-ev-where { font-size: 14.5px; font-weight: 500; color: var(--ink-62); }
.cal-ev-blurb { font-weight: 400; color: var(--ink-80); line-height: 1.5; font-size: 15.5px; }
.cal-ev-why { font-size: 15px; font-weight: 400; color: var(--ink-80); line-height: 1.5; background: var(--corn-12); border-radius: var(--r-in); padding: 12px 14px; }
.cal-ev-why span { display: block; font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.cal-ev-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: auto; padding-top: 12px; }
.cal-ev-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: 15px; }
.cal-ev-link svg { width: 16px; height: 16px; }
.cal-ev-link:hover { text-decoration: underline; text-underline-offset: .18em; }
.cal-ev.is-passed { opacity: .62; }
.status[data-status="tba"]::before { background: transparent; box-shadow: inset 0 0 0 2px var(--ink-45); }
.status[data-status="passed"]::before { background: var(--ink-14); }

/* A day link lands on a card well down the page, so mark where it landed. */
.cal-ev:target { box-shadow: 0 0 0 3px var(--corn), var(--lift-2); }

.cal-month-block { margin-bottom: clamp(28px, 4vw, 48px); }
.cal-month-block:last-child { margin-bottom: 0; }
.cal-month-name {
  font-size: 15px; font-weight: 500; color: var(--ink-62);
  padding-bottom: 12px; margin-bottom: clamp(16px, 2vw, 22px);
  border-bottom: 1px solid var(--ink-14);
}

/* ---------- 11. Responsive ---------- */
@media (max-width: 1100px) {
  .robots-grid, .similar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-art { max-width: 300px; margin-inline: auto; }
  .hero-art .callout { right: -6%; top: 2%; }
  .profile-grid { grid-template-columns: 1fr; }
  .glance { position: static; }
  .teaser { grid-template-columns: 1fr; }
  .profile-body .block-2 { grid-template-columns: 1fr; }
  .save-panel { grid-template-columns: 1fr; }
  .picker { grid-template-columns: 1fr; }
  .cta-band { grid-template-columns: 1fr; }
  .picks { grid-template-columns: 1fr; }
  .third-band { grid-template-columns: 1fr; }
  /* the cover leads on a phone, where it is the first thing worth seeing */
  .guide-grid { grid-template-columns: 1fr; }
  .guide-cover { order: -1; max-width: 340px; }
  /* the routes stack, and the hairline moves from the side to the top */
  .routes { grid-auto-flow: row; }
  .route + .route { border-left: 0; border-top: 1px solid rgba(22, 27, 46, .10); }
  .pay { grid-template-columns: 1fr; align-items: start; }
  .pay .btn { justify-self: start; }
  .site-nav { display: none; position: absolute; left: 0; right: 0; top: var(--header-h); background: var(--cloud); border-bottom: 1px solid var(--ink-14); box-shadow: var(--lift-2); padding: 12px var(--gutter) 20px; }
  .site-nav.open { display: block; }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 4px; }
  /* In the open menu the whole row is the link, not just the word: a thumb or
     a zoomed-in cursor lands anywhere across the row, and before this the right
     side of every row was dead and the menu felt as if it half worked. */
  .site-nav a { display: flex; width: 100%; min-height: 52px; padding: 0 18px; border-radius: var(--r-in); font-size: 17px; }
  .nav-toggle { display: inline-flex; }
}
@media (max-width: 640px) {
  body { font-size: 16px; }
  .robots-grid, .similar { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  /* Booshi keeps the depth but not the whole corner: on a phone the bubble is
     only about 210px wide, and 34px of radius plus 24px of padding leaves the
     sentence with roughly twenty characters a line. */
  .booshi-says .bubble { border-radius: 26px; padding: 16px 18px; }
  .versus { grid-template-columns: 1fr; }
  .vs-mark { justify-self: center; }
  .vs-links { grid-template-columns: 1fr; }
  .hero-actions .btn { width: 100%; }
  .tray { left: 12px; right: 12px; transform: translate(0, 130%); max-width: none; }
  .tray.show { transform: translate(0, 0); }
  .tray .names { max-width: none; flex: 1; }
  .save-panel .inline { grid-template-columns: 1fr; }
  .strip { gap: 8px 20px; font-size: 14.5px; }
  .hero-art { max-width: 240px; }
  .hero-copy { gap: 14px; }
  .hero-copy .display { font-size: clamp(30px, 8.4vw, 38px); max-width: none; }
  .hero-art .callout { display: none; }
  .hero { padding-top: 16px; }
}

/* A pair page that has a written article says so at the top: the page stays the
   interactive view, the article is the read. */
.article-pointer { background: var(--sky); border-radius: var(--r-in); padding: 14px 20px; font-weight: 500; margin-top: 4px; }
.guide-done { font-weight: 400; line-height: 1.55; }
.not-found { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); gap: clamp(24px, 5vw, 56px); align-items: center; padding: clamp(32px, 6vw, 72px) 0; }
.not-found img { justify-self: center; }
@media (max-width: 760px) { .not-found { grid-template-columns: 1fr; } .not-found img { max-width: 200px; } }

/* The empty states are Booshi talking, not a picture with a caption under it:
   the head is round and on Sky, the words are in his bubble. */
.empty { text-align: left; justify-items: stretch; }
.empty .booshi-says { justify-items: start; }
.empty .btn { justify-self: start; margin-left: 70px; }
.booshi-says img { border-radius: 50%; object-fit: cover; }

/* The written comparisons: a light lift and a small step towards the reader,
   so a row answers the cursor instead of sitting there. */
.vs-links a { transition: transform .18s var(--ease), box-shadow .18s var(--ease), background-color .18s var(--ease); }
.vs-links a:hover { transform: translateY(-2px); background: var(--sky); box-shadow: var(--lift-2); color: var(--ink); }
.article-list a { transition: transform .18s var(--ease), box-shadow .18s var(--ease), background-color .18s var(--ease); }
.article-list a:hover { transform: translateY(-2px); background: var(--sky); box-shadow: var(--lift-2); }
@media (prefers-reduced-motion: reduce) {
  .vs-links a:hover, .article-list a:hover { transform: none; }
}

/* A table is data, not prose, so it is not held to the reading measure: it
   runs to the full width of the page and scrolls inside itself below that. */
.article-body .table-scroll { max-width: none; width: min(var(--shell), calc(100vw - 2 * var(--gutter))); }

/* The calendar. It was a page of dates with nothing to look at, and the two
   kinds of entry, a show and a price drop, looked the same. */
.cal-band { margin: 0 0 clamp(20px, 3vw, 32px); display: grid; gap: 8px; }
.cal-band img { width: 100%; height: auto; object-fit: contain; border-radius: var(--r-card); box-shadow: var(--lift-1); }
.cal-band figcaption { font-size: 13px; color: var(--ink-62); }
/* A price drop is money and takes the warm colour; a show is blue. The stripe
   does the telling, so the card can stay quiet. */
.cal-ev { position: relative; overflow: hidden; padding-left: clamp(22px, 2.4vw, 30px); transition: transform .18s var(--ease), box-shadow .18s var(--ease); }
.cal-ev::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px; background: var(--corn); }
.cal-ev:has(.tag-soft) { }
.cal-ev.is-price::before { background: var(--butter); }
.cal-ev:hover { transform: translateY(-2px); box-shadow: var(--lift-2); }
.cal-ev-date { font-size: 17px; letter-spacing: -.01em; }
.cal-ev.is-price .tag-soft { background: var(--butter); color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .cal-ev:hover { transform: none; } }

/* Hover on a robot or an article card: the picture leans in by 4% inside its
   frame and a Butter ring draws round the card. Only on devices that really
   hover, so a tap on a phone does not leave a card stuck in its hover state;
   keyboard focus gets the same ring. */
.robot-card { transition: box-shadow .22s var(--ease); }
.robot-card .plate img, .article-list .thumb { transition: transform .5s var(--ease); }
@media (hover: hover) {
  .robot-card:hover, .article-list a:hover { box-shadow: 0 0 0 2px var(--ring), var(--lift-2); }
  .robot-card:hover .plate img, .article-list a:hover .thumb { transform: scale(1.04); }
}
.robot-card:has(.name a:focus-visible), .article-list a:focus-visible { box-shadow: 0 0 0 2px var(--ring), var(--lift-2); outline: none; }
@media (prefers-reduced-motion: reduce) {
  .robot-card .plate img, .article-list .thumb { transition: none; }
  .robot-card:hover .plate img, .article-list a:hover .thumb { transform: none; }
}

/* ---------- 14. Small pleasures ---------- */

/* Selected text takes the warm spot instead of the browser's blue. */
::selection { background: var(--butter); color: var(--ink); }

/* A sale shows its saving next to the struck price. */
.tag-save { background: var(--cloud); color: var(--ink); box-shadow: inset 0 0 0 2px var(--ring); }
.price-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* The written comparisons answer hover the same way the cards do. */
@media (hover: hover) {
  .vs-links a:hover { box-shadow: 0 0 0 2px var(--ring), var(--lift-2); }
}

/* Booshi floats, and leans toward the pointer. The float moves `translate`,
   the lean sets `transform` on the same wrapper, and the landing animation
   keeps its own `transform` on the picture, so none of the three fight. The
   shadow stays on the floor and shrinks as he rises. */
.hero-art .booshi-body { position: relative; display: grid; place-items: center; width: 100%; transform: perspective(900px) rotateY(var(--ry, 0deg)) rotateX(var(--rx, 0deg)); transition: transform .6s var(--ease); animation: booshi-float 5.5s ease-in-out 1s infinite; }
.hero-art .booshi-body img { filter: drop-shadow(0 18px 22px rgba(22, 27, 46, .12)); }
.hero-art .booshi-shadow { position: absolute; bottom: 3%; left: 50%; width: 46%; height: 5%; margin-left: -23%; border-radius: 50%; background: radial-gradient(closest-side, rgba(22, 27, 46, .22), transparent); animation: booshi-shadow 5.5s ease-in-out 1s infinite; }
@keyframes booshi-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -12px; } }
@keyframes booshi-shadow { 0%, 100% { scale: 1; opacity: 1; } 50% { scale: .82; opacity: .7; } }

/* Hearts float up like balloons. Three separate motions, each one smooth on
   its own, so nothing stops and starts: the rise is one long glide that slows
   as it goes, the sway is a pendulum swinging side to side, and the pop is a
   quick grow at the start. Each moves a different property (translate,
   transform, scale), so they add up instead of fighting. No filters: a
   shadow on a moving shape is repainted every frame and makes it stutter. */
.heart-float { position: fixed; z-index: 950; width: 0; height: 0; pointer-events: none; }
.heart-float svg { position: absolute; left: -11px; top: -11px; width: 22px; height: 22px; max-width: none; opacity: 0; will-change: transform, translate, opacity;
  animation: balloon-rise var(--t, 2s) cubic-bezier(.3, .7, .4, 1) both, balloon-sway var(--p, 1s) ease-in-out infinite alternate both, balloon-pop .45s cubic-bezier(.34, 1.4, .64, 1) both; }
.heart-float svg path, .heart-flyer svg path { stroke: none; }
@keyframes balloon-rise {
  0% { translate: 0 0; opacity: 0; }
  8% { opacity: 1; }
  70% { opacity: 1; }
  100% { translate: var(--x) var(--rise); opacity: 0; }
}
@keyframes balloon-sway {
  from { transform: translateX(calc(var(--sway) * -1)) rotate(-9deg); }
  to { transform: translateX(var(--sway)) rotate(9deg); }
}
@keyframes balloon-pop { from { scale: .3; } to { scale: var(--s, 1); } }
/* The heart that flies to "My robots". */
.heart-flyer { position: fixed; left: 0; top: 0; z-index: 960; width: 26px; height: 26px; margin: -13px 0 0 -13px; pointer-events: none; will-change: transform, opacity; }
.heart-flyer svg { width: 100%; height: 100%; max-width: none; }
.bump { animation: count-bump .5s var(--spring); }
@keyframes count-bump { 0% { transform: scale(1); } 40% { transform: scale(1.45); } 100% { transform: scale(1); } }

/* Pictures arrive softly instead of painting in strips. Only images still
   loading are hidden, and only by script, so nothing is ever hidden without it. */
img.is-loading { opacity: 0; }
img.is-loaded { transition: opacity .45s var(--ease); }

/* A pill that slides under the menu from one item to the next. */
.site-nav ul { position: relative; }
.nav-glide { position: absolute; left: 0; top: 50%; height: 40px; margin-top: -20px; border-radius: var(--r-pill); background: var(--corn-12); opacity: 0; pointer-events: none; transition: transform .35s var(--spring), width .35s var(--spring), opacity .2s var(--ease); z-index: 0; }
.site-nav li { position: relative; z-index: 1; }
.site-nav.has-glide a:hover { background: transparent; }
.site-nav.has-glide.gliding a[aria-current="page"] { background: transparent; }

/* The robot's photo opens large. */
.profile-media .plate.has-photo img { cursor: zoom-in; }
.lightbox { padding: 0; border: 0; border-radius: var(--r-card); background: var(--sky); box-shadow: var(--lift-2); width: min(1000px, 94vw); max-height: 92vh; overflow: hidden; }
.lightbox::backdrop { background: rgba(22, 27, 46, .55); backdrop-filter: blur(4px); }
.lightbox img { display: block; width: 100%; height: auto; max-height: 92vh; object-fit: contain; cursor: zoom-out; }
.lightbox .close { position: absolute; top: 14px; right: 14px; width: 44px; height: 44px; border-radius: 50%; background: var(--cloud); box-shadow: var(--lift-1); font-size: 26px; line-height: 1; }
.lightbox[open] { animation: lightbox-in .3s var(--spring); }
@keyframes lightbox-in { from { opacity: 0; transform: scale(.96); } }

/* How far through the article you are, drawn by the scroll itself, no script. */
.read-progress { display: none; }
@supports (animation-timeline: scroll()) {
  .read-progress { display: block; position: fixed; left: 0; right: 0; top: 0; height: 3px; z-index: 200; background: var(--corn); transform-origin: 0 50%; transform: scaleX(0); animation: read-grow linear both; animation-timeline: scroll(root); }
  @keyframes read-grow { to { transform: scaleX(1); } }
}

/* Questions open smoothly instead of jumping, where the browser can animate
   to an automatic height; elsewhere they simply open. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .faq details::details-content, .toc-mini::details-content { height: 0; overflow: clip; transition: height .35s var(--ease), content-visibility .35s allow-discrete; }
  .faq details[open]::details-content, .toc-mini[open]::details-content { height: auto; }
}

/* The contents list. On a wide screen it sits beside the article and stays in
   view; the article keeps its reading measure and a table may still run the
   full width of its own column. On a narrow screen it is a pill under the
   header that opens into the list. */
.toc ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.toc a { display: block; padding: 8px 12px; border-radius: var(--r-in); font-size: 15px; line-height: 1.35; color: var(--ink-80); font-weight: 500; transition: background-color .16s var(--ease), color .16s var(--ease); }
.toc a:hover { background: var(--corn-12); color: var(--ink); }
.toc a[aria-current="true"] { background: var(--sky); color: var(--ink); box-shadow: inset 3px 0 0 var(--corn); }
.toc-side { display: none; }
.toc-mini { position: sticky; top: calc(var(--header-h) + 8px); z-index: 50; margin-bottom: 24px; background: var(--cloud); border-radius: var(--r-in); box-shadow: var(--lift-1); }
.toc-mini summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; min-height: 48px; padding: 0 16px; font-weight: 600; font-size: 16px; }
.toc-mini summary::-webkit-details-marker { display: none; }
.toc-mini summary::after { content: ""; width: 10px; height: 10px; border-right: 2px solid var(--ink); border-bottom: 2px solid var(--ink); transform: translateY(-3px) rotate(45deg); transition: transform .2s var(--ease); }
.toc-mini[open] summary::after { transform: translateY(2px) rotate(-135deg); }
.toc-mini ol { padding: 0 8px 12px; max-height: 60vh; overflow: auto; }
@media (min-width: 1100px) {
  .article-layout.has-toc { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 56px; align-items: start; }
  .article-layout.has-toc .toc-mini { display: none; }
  .article-layout.has-toc .toc-side { display: block; position: sticky; top: calc(var(--header-h) + 24px); max-height: calc(100vh - var(--header-h) - 48px); overflow: auto; padding: 18px 12px; border-radius: var(--r-card); background: var(--cloud); box-shadow: var(--lift-1); }
  .toc-title { font-family: var(--display); font-weight: 700; font-size: 18px; padding: 0 12px 10px; }
  .article-layout.has-toc .article-body .table-scroll { width: calc(min(var(--shell), 100vw - 2 * var(--gutter)) - 260px - 56px); }
}

/* Moving between pages: the page cross-fades, the header holds still, and a
   robot's photo travels from its card to its own page and back. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.site-header { view-transition-name: site-header; }
::view-transition-group(rb-photo) { animation-duration: .5s; animation-timing-function: cubic-bezier(.22, .61, .36, 1); }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .25s; }

@media (prefers-reduced-motion: reduce) {
  .hero-art .booshi-body { transform: none; }
  img.is-loading { opacity: 1; }
}

/* Booshi blinks, and now and then winks. Only the band of screen around his
   eyes is swapped, laid exactly over the picture, so a slightly different
   render of the body in the source drawings never shows. */
.hero-art .booshi-frame { position: relative; width: min(100%, 440px); }
.hero-art .booshi-frame img { width: 100%; }
.booshi-eyes { position: absolute; left: 30.568%; top: 32.169%; width: 38.865%; height: 16.448%; background: center / 100% 100% no-repeat; opacity: 0; pointer-events: none; }
.booshi-eyes.closed { background-image: url("/assets/img/mascot/booshi-eyes-closed.webp"); }
.booshi-eyes.wink { background-image: url("/assets/img/mascot/booshi-eyes-wink.webp"); }
.booshi-eyes.on { opacity: 1; }

/* The round Booshi in the speech bubbles is cut from the same drawing as the
   home page one, so the same eye bands fit him. */
.booshi-avatar { position: relative; display: block; width: 56px; height: 56px; border-radius: 50%; overflow: hidden; box-shadow: var(--clay-lift); }
.booshi-says .booshi-avatar img { box-shadow: none; }
.booshi-avatar .booshi-eyes { left: 24.773%; top: 54.773%; width: 50.568%; height: 25.682%; }

/* Calendar hero: the words sit on the picture. The top of the picture is
   faded into the page with a mask, so the wall above the shelf turns to the
   page's own colour and the headline stands on it, while the robots stay
   whole below. On a narrow screen the words come first and the picture,
   still fading in at the top, follows. */
.cal-stage { display: grid; }
.cal-scene { margin: 0; display: grid; gap: 8px; }
.cal-scene img { width: 100%; height: auto; border-radius: 0 0 var(--r-card) var(--r-card); -webkit-mask-image: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, .35) 16%, #000 34%); mask-image: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, .35) 16%, #000 34%); }
.cal-scene figcaption { font-size: 13px; color: var(--ink-62); justify-self: end; }
.cal-hero-copy { position: relative; z-index: 1; }
@media (min-width: 960px) {
  /* The robots' heads start about 27% down the picture, and the picture is
     52% as tall as it is wide, so they sit 14% of the stage width below its
     top edge. The picture is pushed down just far enough to put them clear of
     the buttons: the height of the words, less that 14%. */
  .cal-stage { container-type: inline-size; }
  .cal-stage > * { grid-area: 1 / 1; }
  .cal-hero-copy { align-self: start; max-width: 720px; gap: 16px; }
  .cal-hero-copy .display { max-width: 20ch; }
  .cal-hero-copy .lede { max-width: 54ch; }
  .cal-scene { margin-top: max(40px, calc(var(--cal-words, 330px) + 24px - 14.1cqw)); }
  .cal-scene img { -webkit-mask-image: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, .3) 12%, #000 25%); mask-image: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, .3) 12%, #000 25%); }
}
@media (max-width: 959px) {
  .cal-scene { margin-top: -8px; }
}

/* Below the hero: Booshi's advice beside the month at a glance. */
.cal-intro { display: grid; gap: 24px; align-items: start; margin-top: clamp(8px, 2vw, 24px); }
@media (min-width: 960px) {
  .cal-intro { grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); gap: 48px; }
}

/* Sortable tables: the whole heading is the button; a small pair of
   chevrons shows it sorts, and the active column shows which way. */
.table-hint { font-size: 14px; color: var(--ink-62); margin-bottom: 8px; }
.article-table[data-sortable] thead th { padding: 0; }
.article-table thead .sort { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 48px; padding: 13px 16px; font: inherit; color: inherit; text-align: left; background: transparent; border: 0; cursor: pointer; white-space: nowrap; transition: background-color .16s var(--ease); }
.article-table thead .sort:hover { background: rgba(250, 247, 242, .08); }
.article-table thead .sort:focus-visible { outline: 2px solid var(--corn); outline-offset: -2px; }
.sort-ico { flex: none; width: 8px; height: 12px; opacity: .45; }
.sort-ico { background:
  conic-gradient(from 135deg at 50% 0, currentColor 90deg, transparent 0) top / 8px 4px no-repeat,
  conic-gradient(from -45deg at 50% 100%, currentColor 90deg, transparent 0) bottom / 8px 4px no-repeat; }
th[aria-sort] .sort-ico { opacity: 1; }
th[aria-sort="ascending"] .sort-ico { background: conic-gradient(from 135deg at 50% 0, currentColor 90deg, transparent 0) center / 8px 4px no-repeat; }
th[aria-sort="descending"] .sort-ico { background: conic-gradient(from -45deg at 50% 100%, currentColor 90deg, transparent 0) center / 8px 4px no-repeat; }
th[aria-sort] .sort { color: var(--sky); text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 2px; }

/* Article cards: three to a row and larger, on the articles page and the
   home page alike. */
.article-list { grid-template-columns: 1fr; gap: 22px; }
@media (min-width: 600px) { .article-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .article-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px; } }
.article-list a:has(.thumb) { padding-bottom: 24px; border-radius: var(--r-card); }
.article-list a:has(.thumb) > span { padding: 0 22px; }
.article-list .thumb { margin-bottom: 12px; }
.article-list .title { font-size: clamp(19px, 1.5vw, 21px); line-height: 1.28; letter-spacing: -.005em; }
.article-list .blurb { font-size: 15.5px; }
.article-grid { margin-top: 8px; }

/* ---------- 15. The Money Playbook ---------- */
.btn-lg { min-height: 56px; padding-inline: 28px; font-size: 17px; }
.btn.is-pending { cursor: default; opacity: .72; }

/* The cover leans in beside the headline and straightens when pointed at:
   the one bit of play on a page that otherwise just explains. */
.pb-hero { padding-block: clamp(28px, 5vw, 72px) clamp(36px, 5vw, 72px); }
.pb-hero-grid { display: grid; gap: clamp(28px, 5vw, 64px); align-items: center; }
.pb-hero-copy { display: grid; gap: 20px; justify-items: start; }
.pb-hero-copy .display { max-width: 14ch; }
.pb-hero-copy .lede { max-width: 50ch; }
/* Launch price: the one she charges, the full one struck through beside it. */
.pb-price { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: 0; }
.pb-now { font-family: var(--display); font-weight: 700; font-size: clamp(34px, 3.4vw, 44px); letter-spacing: -.01em; line-height: 1; }
.pb-was { font-size: 22px; color: var(--ink-80); text-decoration-thickness: 2px; }
.pb-cover { margin: 0; justify-self: center; width: min(100%, 380px); }
/* The book on the home page: cover and pitch, on a Sky card. */
.pb-teaser { display: grid; gap: clamp(24px, 4vw, 56px); align-items: center; padding: clamp(24px, 4vw, 56px); border-radius: var(--r-card); background: var(--sky); }
.pb-teaser-cover { justify-self: center; width: min(100%, 260px); }
.pb-teaser-cover img { width: 100%; height: auto; border-radius: 12px; box-shadow: var(--clay-lift); transform: rotate(-3deg); transition: transform .5s var(--spring); }
@media (hover: hover) { .pb-teaser:hover .pb-teaser-cover img { transform: rotate(0deg) translateY(-4px); } }
.pb-teaser-copy { display: grid; gap: 16px; justify-items: start; }
.pb-teaser-copy .lede { max-width: 52ch; }
@media (min-width: 760px) { .pb-teaser { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); } }
/* Inside an article the card keeps its own type, not the prose rules. */
.article-body .pb-teaser { margin-block: 2.4em 0; padding: clamp(22px, 3vw, 36px); font-size: 17px; line-height: 1.5; }
.article-body .pb-teaser h2 { margin-top: 0; font-size: clamp(26px, 2.8vw, 34px); }
.article-body .pb-teaser-cover { width: min(100%, 200px); }
.article-body .pb-teaser a { text-decoration: none; }
.pb-cover img { width: 100%; height: auto; border-radius: 14px; box-shadow: var(--clay-lift); transform: rotate(3deg); transition: transform .5s var(--spring); }
@media (hover: hover) { .pb-cover:hover img { transform: rotate(0deg) translateY(-4px); } }
@media (min-width: 900px) {
  .pb-hero-grid { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
}

.pb-readers { display: grid; gap: 18px; margin-top: 24px; }
@media (min-width: 700px) { .pb-readers { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pb-reader { padding: 22px 24px; border-radius: var(--r-card); background: var(--cloud); box-shadow: var(--lift-1); }
.pb-reader h3 { margin-bottom: 6px; }
.pb-reader p { color: var(--ink-80); line-height: 1.55; }

.pb-lede { margin-top: 10px; }
.pb-four { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 30px; padding: 0; list-style: none; }
.pb-four li { padding: 9px 16px; border-radius: var(--r-pill); background: var(--cloud); font-weight: 600; font-size: 15.5px; }
.pb-tracks { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }
@media (min-width: 640px) { .pb-tracks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .pb-tracks { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.pb-track { display: grid; gap: 8px; align-content: start; padding: 22px 24px 24px; border-radius: var(--r-card); background: var(--cloud); box-shadow: var(--lift-1); }
.pb-count { font-size: 15px; color: var(--ink-62); font-weight: 500; }
.pb-count b { font-family: var(--display); font-weight: 700; font-size: 34px; line-height: 1; color: var(--corn); margin-right: 4px; }
.pb-track p { color: var(--ink-80); line-height: 1.55; font-size: 15.5px; }

.pb-split { display: grid; gap: 28px; margin-bottom: 32px; }
@media (min-width: 800px) { .pb-split { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 48px; } }
.pb-split .prose { margin-top: 10px; }

.pb-final .btn { flex: none; }

.pb-thanks { display: grid; gap: 28px; padding-block: clamp(32px, 6vw, 80px); max-width: 760px; }
.pb-thanks-card { display: grid; gap: 18px; justify-items: start; padding: clamp(24px, 4vw, 40px); border-radius: var(--r-card); background: var(--sky); }
