/* ChalkSprout design system
   ---------------------------------------------------------------------------
   Audience: US elementary teachers and parents arriving from Pinterest.
   The brief that shapes every decision below:

   - Friendly, but unmistakably FOR ADULTS. A site that reads as child-directed
     gets classified as such by ad networks and loses personalised ads, which
     collapses revenue. So: warm and human, never bubbly or primary-coloured.
   - Fast. The product is a download; anything that delays it is a bug.
   - Legible on a phone held in one hand in a school corridor.

   Palette: an airy off-white ground with a deep botanical green — the sprout in
   the name. Neutrals carry a slight green bias so they read as chosen rather
   than inherited. One accent only; the honey tone is reserved for the "free"
   badge and nothing else.
--------------------------------------------------------------------------- */

:root {
  /* surfaces */
  --ground: #F7F8F5;
  --surface: #FFFFFF;
  --surface-sunken: #EFF2EC;
  --surface-raised: #FFFFFF;

  /* ink */
  --ink: #161A17;
  --ink-soft: #3D453F;
  --muted: #626C66;
  --rule: #E3E7E0;
  --rule-strong: #CFD6CB;

  /* brand */
  --accent: #2F6B4F;
  --accent-hover: #255741;
  --accent-ink: #FFFFFF;
  --accent-wash: #ECF3EE;
  --accent-ring: rgba(47, 107, 79, .32);

  /* the one secondary, used only for the free badge */
  --honey: #8A6410;
  --honey-wash: #FBF3E0;

  --danger: #A8412F;
  --danger-wash: #FBEEEB;

  /* type */
  --font-display: ui-rounded, "SF Pro Rounded", "Segoe UI Variable Display",
                  "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --step--1: clamp(.82rem, .8rem + .1vw, .875rem);
  --step-0:  clamp(1rem, .97rem + .15vw, 1.0625rem);
  --step-1:  clamp(1.15rem, 1.1rem + .25vw, 1.28rem);
  --step-2:  clamp(1.38rem, 1.28rem + .5vw, 1.65rem);
  --step-3:  clamp(1.7rem, 1.5rem + 1vw, 2.25rem);
  --step-4:  clamp(2.1rem, 1.7rem + 2vw, 3rem);

  /* rhythm */
  --sp-1: .25rem; --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.5rem; --sp-6: 2rem;   --sp-7: 3rem;   --sp-8: 4.5rem;

  --radius: 12px;
  --radius-sm: 8px;
  --radius-pill: 999px;

  --shadow-1: 0 1px 1px rgba(22, 26, 23, .04);
  --shadow-2: 0 1px 2px rgba(22, 26, 23, .04), 0 12px 32px -8px rgba(22, 26, 23, .12);
  --shadow-sheet: 0 1px 1px rgba(22, 26, 23, .05),
                  0 8px 24px -6px rgba(22, 26, 23, .10),
                  0 24px 56px -20px rgba(22, 26, 23, .14);
  --shadow-accent: 0 1px 2px rgba(47, 107, 79, .2), 0 10px 24px -8px rgba(47, 107, 79, .34);

  --ease: cubic-bezier(.2, .7, .3, 1);
  --dur-1: 140ms;
  --dur-2: 240ms;

  --measure: 38rem;
  --wide: 68rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #101310;
    --surface: #171B18;
    --surface-sunken: #1D221E;
    --surface-raised: #1D221E;
    --ink: #E7ECE7;
    --ink-soft: #C2CBC4;
    --muted: #93A096;
    --rule: #2A312C;
    --rule-strong: #3A433D;
    --accent: #7FC49C;
    --accent-hover: #96D3AF;
    --accent-ink: #0E1A13;
    --accent-wash: #1A2620;
    --accent-ring: rgba(127, 196, 156, .38);
    --honey: #E0B75E;
    --honey-wash: #2A2313;
    --danger: #E58A76;
    --danger-wash: #2B1B17;
    --shadow-1: 0 1px 1px rgba(0, 0, 0, .3);
    --shadow-2: 0 1px 2px rgba(0, 0, 0, .3), 0 12px 32px -8px rgba(0, 0, 0, .55);
    --shadow-sheet: 0 1px 2px rgba(0, 0, 0, .4), 0 24px 56px -20px rgba(0, 0, 0, .7);
    --shadow-accent: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 24px -8px rgba(0, 0, 0, .6);
  }
}

:root[data-theme="dark"] {
  --ground: #101310; --surface: #171B18; --surface-sunken: #1D221E; --surface-raised: #1D221E;
  --ink: #E7ECE7; --ink-soft: #C2CBC4; --muted: #93A096;
  --rule: #2A312C; --rule-strong: #3A433D;
  --accent: #7FC49C; --accent-hover: #96D3AF; --accent-ink: #0E1A13;
  --accent-wash: #1A2620; --accent-ring: rgba(127, 196, 156, .38);
  --honey: #E0B75E; --honey-wash: #2A2313;
  --danger: #E58A76; --danger-wash: #2B1B17;
  --shadow-1: 0 1px 1px rgba(0, 0, 0, .3);
  --shadow-2: 0 1px 2px rgba(0, 0, 0, .3), 0 12px 32px -8px rgba(0, 0, 0, .55);
  --shadow-sheet: 0 1px 2px rgba(0, 0, 0, .4), 0 24px 56px -20px rgba(0, 0, 0, .7);
  --shadow-accent: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 24px -8px rgba(0, 0, 0, .6);
}

/* --------------------------------------------------------------- reset */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  background-color: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

/* Only surfaces cross-fade when the theme flips; everything else would shimmer. */
@media (prefers-reduced-motion: no-preference) {
  .masthead, .card, .tile, .btn, .puzzle, .puzzle span, .bingo-card, .bingo-card span,
  .input, .select, .textarea, .chip, .site-footer, .notice {
    transition-property: background-color, border-color, color, box-shadow, transform;
    transition-duration: var(--dur-2);
    transition-timing-function: var(--ease);
  }
  .btn, .tile, .chip { transition-duration: var(--dur-1), var(--dur-1), var(--dur-1), var(--dur-1), var(--dur-1); }
}

img, svg, canvas { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; }

:where(a):focus-visible,
:where(button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--accent-wash); color: var(--ink); }

/* --------------------------------------------------------------- type */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -.015em;
  text-wrap: balance;
  color: var(--ink);
}
h1 { font-size: var(--step-4); letter-spacing: -.03em; }
h2 { font-size: var(--step-2); letter-spacing: -.012em; }
h3 { font-size: var(--step-1); }
p, li { text-wrap: pretty; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--accent-hover); }

.eyebrow {
  font-family: var(--font-body);
  font-size: .7rem;
  font-weight: 650;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}
/* Digits that sit in columns should never jitter as they change. */
.meta, .wordlist, .puzzle span { font-variant-numeric: tabular-nums; }
.lede { font-size: var(--step-1); color: var(--ink-soft); max-width: var(--measure); }
.meta { font-family: var(--font-mono); font-size: var(--step--1); color: var(--muted); letter-spacing: .02em; }
.prose { max-width: var(--measure); display: flex; flex-direction: column; gap: var(--sp-4); }
.prose h2 { margin-top: var(--sp-4); }
.prose ul, .prose ol { padding-left: 1.15rem; display: flex; flex-direction: column; gap: var(--sp-2); }

/* --------------------------------------------------------------- layout */

.shell { width: 100%; max-width: var(--wide); margin-inline: auto; padding-inline: var(--sp-5); }
.shell--narrow { max-width: 52rem; }
main { flex: 1; padding-block: var(--sp-6) var(--sp-8); }
.stack { display: flex; flex-direction: column; gap: var(--sp-5); }
.stack--tight { gap: var(--sp-3); }
.stack--loose { gap: var(--sp-7); }

/* --------------------------------------------------------------- header */

.masthead {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}
.masthead__inner { display: flex; align-items: center; gap: var(--sp-5); min-height: 3.75rem; }
.brand {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.1rem;
  letter-spacing: -.02em; color: var(--ink); text-decoration: none;
}
.brand__mark {
  width: 1.6rem; height: 1.6rem; flex: none;
  color: var(--accent);
  transition: transform var(--dur-2) var(--ease);
}
.brand:hover .brand__mark { transform: rotate(-8deg) scale(1.06); }
.nav { margin-left: auto; display: flex; align-items: center; gap: var(--sp-1); }
.nav a {
  padding: .4rem .7rem; border-radius: var(--radius-sm);
  font-size: var(--step--1); font-weight: 500; color: var(--muted);
  text-decoration: none; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.nav a:hover { background: var(--surface-sunken); color: var(--ink); }
.nav a[aria-current="page"] { color: var(--accent); background: var(--accent-wash); }

/* --------------------------------------------------------------- buttons */

.btn {
  --btn-bg: var(--surface);
  --btn-ink: var(--ink);
  --btn-edge: var(--rule-strong);
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .62rem 1.05rem;
  background: var(--btn-bg); color: var(--btn-ink);
  border: 1px solid var(--btn-edge); border-radius: var(--radius-sm);
  font-size: var(--step--1); font-weight: 600; text-decoration: none;
  cursor: pointer; white-space: nowrap;
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-2); color: var(--btn-ink); }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-1); }
.btn--primary { --btn-bg: var(--accent); --btn-ink: var(--accent-ink); --btn-edge: var(--accent); }
.btn--primary:hover { --btn-bg: var(--accent-hover); --btn-edge: var(--accent-hover); }
.btn--ghost { --btn-bg: transparent; --btn-edge: var(--rule); box-shadow: none; }
.btn--lg { padding: .8rem 1.35rem; font-size: var(--step-0); }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* --------------------------------------------------------------- badges */

.badge {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .18rem .55rem; border-radius: var(--radius-pill);
  font-size: .72rem; font-weight: 650; letter-spacing: .02em;
  background: var(--accent-wash); color: var(--accent);
}
.badge--free { background: var(--honey-wash); color: var(--honey); }

/* --------------------------------------------------------------- cards */

.card {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: var(--sp-5);
  box-shadow: var(--shadow-1);
}
.grid-cards { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); list-style: none; padding: 0; }
.tile {
  display: flex; flex-direction: column; gap: var(--sp-1);
  padding: var(--sp-4) var(--sp-4) var(--sp-4);
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius); text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease);
}
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); border-color: var(--accent); color: var(--ink); }
.tile strong { font-family: var(--font-display); font-size: var(--step-0); font-weight: 650; }
.tile span { font-size: var(--step--1); color: var(--muted); }

/* --------------------------------------------------------------- hero */

.hero {
  display: grid; gap: var(--sp-5);
  padding: var(--sp-7) 0 var(--sp-6);
}
.hero h1 { max-width: 18ch; }
.hero .lede { font-size: var(--step-1); }
.trust { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font-size: var(--step--1); color: var(--muted); }
.trust li { display: flex; align-items: center; gap: .4rem; list-style: none; }
.trust svg { width: 1rem; height: 1rem; color: var(--accent); flex: none; }

/* --------------------------------------------------------------- puzzle grid */

/* Hairlines come from the container showing through a 1px gap, so the outer
   edge stays clean without nth-child gymnastics at every grid size. */
.puzzle {
  display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: 1px; background: var(--rule);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm);
  overflow: hidden;
  max-width: 34rem; margin-inline: auto; width: 100%;
  box-shadow: var(--shadow-1);
}
.puzzle span {
  aspect-ratio: 1; display: grid; place-items: center;
  background: var(--surface);
  font-family: var(--font-mono); font-weight: 700;
  font-size: clamp(.5rem, calc(30rem / var(--cols) / 2.4), 1.05rem);
  color: var(--ink);
}

.wordlist {
  list-style: none; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: var(--sp-1) var(--sp-4);
  font-family: var(--font-mono); font-size: var(--step--1);
}

.bingo-preview {
  display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.bingo-card {
  display: grid; grid-template-columns: repeat(var(--cols), 1fr);
  gap: 1px; background: var(--rule);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm);
  overflow: hidden; box-shadow: var(--shadow-1);
}
.bingo-card span {
  aspect-ratio: 1; display: grid; place-items: center; text-align: center;
  background: var(--surface);
  padding: 2px; font-size: clamp(.44rem, calc(11rem / var(--cols) / 3.4), .72rem);
  font-weight: 600; line-height: 1.1; overflow: hidden;
}
.bingo-card span.free { color: var(--accent); background: var(--accent-wash); }

/* --------------------------------------------------------------- maker */

.maker { display: grid; gap: var(--sp-5); align-items: start; }
@media (min-width: 60rem) {
  .maker { grid-template-columns: 20rem minmax(0, 1fr); gap: var(--sp-6); }
  .maker__controls { position: sticky; top: 5rem; }
}
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field > label, .field > .label {
  font-size: var(--step--1); font-weight: 650; color: var(--ink-soft);
}
.field .hint { font-size: .8rem; color: var(--muted); }
.input, .select, .textarea {
  width: 100%; padding: .55rem .7rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--muted); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}
.textarea { min-height: 9.5rem; resize: vertical; font-family: var(--font-mono); font-size: .84rem; line-height: 1.75; }
.range { width: 100%; accent-color: var(--accent); }
.switch { display: flex; align-items: center; gap: .55rem; font-size: var(--step--1); cursor: pointer; }
.switch input { accent-color: var(--accent); width: 1.05rem; height: 1.05rem; }

.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  padding: .28rem .68rem; border-radius: var(--radius-pill);
  border: 1px solid var(--rule-strong); background: var(--surface);
  font-size: .82rem; cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.chip:hover { border-color: var(--accent); transform: translateY(-1px); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }

.notice {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm);
  font-size: var(--step--1); border: 1px solid var(--rule);
}
.notice--warn { background: var(--danger-wash); border-color: color-mix(in srgb, var(--danger) 35%, transparent); color: var(--danger); }
.notice--info { background: var(--accent-wash); border-color: color-mix(in srgb, var(--accent) 25%, transparent); color: var(--accent); }

/* --------------------------------------------------------------- misc */

.crumbs { display: flex; flex-wrap: wrap; gap: .35rem; font-size: var(--step--1); color: var(--muted); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs span[aria-hidden] { opacity: .45; }

.pin-preview {
  width: 190px; aspect-ratio: 2 / 3; object-fit: contain;
  border: 1px solid var(--rule); border-radius: var(--radius-sm); background: #fff;
  box-shadow: var(--shadow-1);
}
.split { display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); align-items: start; }

.divider { height: 1px; background: var(--rule); border: 0; }

.site-footer {
  border-top: 1px solid var(--rule); background: var(--surface);
  padding-block: var(--sp-6); font-size: var(--step--1); color: var(--muted);
}
.site-footer nav { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.site-footer a { color: var(--muted); text-decoration: none; }
.site-footer a:hover { color: var(--accent); text-decoration: underline; }

.skip-link {
  position: absolute; left: var(--sp-4); top: -4rem; z-index: 100;
  padding: .6rem 1rem; background: var(--accent); color: var(--accent-ink);
  border-radius: var(--radius-sm); font-weight: 600; text-decoration: none;
  transition: top var(--dur-2) var(--ease);
}
.skip-link:focus { top: var(--sp-3); color: var(--accent-ink); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------- motion */

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.rise { animation: rise var(--dur-2) var(--ease) both; }
.rise:nth-child(2) { animation-delay: 45ms; }
.rise:nth-child(3) { animation-delay: 90ms; }
.rise:nth-child(4) { animation-delay: 135ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .btn:hover, .tile:hover, .chip:hover { transform: none; }
}

/* --------------------------------------------------------------- print */

@media print {
  .masthead, .site-footer, .btn-row, .maker__controls, .skip-link, .crumbs { display: none !important; }
  body { background: #fff; color: #000; }
  .puzzle, .card { box-shadow: none; border-color: #999; }
}

/* --------------------------------------------------------------- theme toggle */

.theme-toggle {
  flex: none;
  display: grid; place-items: center;
  width: 2.25rem; height: 2.25rem;
  margin-left: var(--sp-1);
  border: 1px solid var(--rule); border-radius: var(--radius-sm);
  color: var(--muted); cursor: pointer;
  background: var(--surface);
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.theme-toggle:hover { color: var(--accent); border-color: var(--accent); transform: translateY(-1px); }
.theme-toggle:active { transform: translateY(0); }
.theme-toggle__icon { width: 1.1rem; height: 1.1rem; grid-area: 1 / 1; }

/* Exactly one icon is visible; which one is driven by the button's data-mode.
   Before the script runs, data-mode is absent and the auto icon shows — which is
   also the default behaviour, so there is nothing to flash. */
.theme-toggle__icon--light,
.theme-toggle__icon--dark { display: none; }
.theme-toggle[data-mode="light"] .theme-toggle__icon--auto,
.theme-toggle[data-mode="dark"]  .theme-toggle__icon--auto { display: none; }
.theme-toggle[data-mode="light"] .theme-toggle__icon--light { display: block; }
.theme-toggle[data-mode="dark"]  .theme-toggle__icon--dark  { display: block; }

@media (prefers-reduced-motion: no-preference) {
  .theme-toggle__icon { animation: iconIn var(--dur-2) var(--ease); }
}
@keyframes iconIn {
  from { opacity: 0; transform: rotate(-25deg) scale(.85); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------- polish */

/* The masthead only grows a shadow once the page has scrolled under it. */
.masthead { box-shadow: 0 1px 0 var(--rule); }

/* Primary buttons get a lit top edge and a coloured shadow, so the main action
   reads as raised rather than merely filled. */
.btn--primary {
  box-shadow: var(--shadow-accent);
  background-image: linear-gradient(to bottom, rgba(255, 255, 255, .14), transparent 55%);
}
.btn--primary:hover { box-shadow: var(--shadow-accent), 0 4px 10px rgba(0, 0, 0, .06); }

/* Tiles answer with the title, not with an accent bar down the side — that rail
   is one of the most recognisable tells of templated design. */
.tile { position: relative; }
.tile strong { transition: color var(--dur-1) var(--ease); }
.tile:hover strong, .tile:focus-visible strong { color: var(--accent); }

/* Section headings get a short rule that inherits the accent. */
.section-title { display: flex; align-items: center; gap: var(--sp-3); }
.section-title::after {
  content: ""; flex: 1; height: 1px; background: var(--rule);
}

.hero { position: relative; }
.hero h1 { letter-spacing: -.025em; }
.hero .btn-row { margin-top: var(--sp-1); }

.trust li { transition: color var(--dur-1) var(--ease); }
.trust li:hover { color: var(--ink); }

.card { transition: border-color var(--dur-2) var(--ease); }
.maker__controls { max-height: calc(100vh - 6.5rem); overflow-y: auto; }
@media (max-width: 60rem) { .maker__controls { max-height: none; overflow: visible; } }

/* The puzzle is the product: give it a touch more presence than a plain card. */
.puzzle { box-shadow: var(--shadow-2); }
.puzzle span { transition: background-color var(--dur-1) var(--ease); }
.puzzle:hover span { background: var(--surface); }

.badge { border: 1px solid color-mix(in srgb, currentColor 22%, transparent); }

.crumbs a { transition: color var(--dur-1) var(--ease); }

/* Comfortable tap targets on touch devices, without inflating the desktop UI. */
@media (pointer: coarse) {
  .nav a { padding: .55rem .8rem; }
  .chip { padding: .42rem .85rem; }
  .theme-toggle { width: 2.5rem; height: 2.5rem; }
}

/* On narrow screens the nav labels shorten rather than wrapping or scrolling. */
@media (max-width: 30rem) {
  .masthead__inner { gap: var(--sp-2); }
  .brand { font-size: 1rem; }
  .nav a { padding: .4rem .45rem; font-size: .8rem; }
}

/* --------------------------------------------------------------- the sheet */

/* The worksheet is the product, so it is drawn as a physical sheet resting on
   the page rather than as another rounded card. This is the one place the design
   spends its depth budget — everything else stays flat so this reads as an object.
   No paper texture, no tilt, no torn edge: the restraint is what sells it. */

.sheet {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 4px;                 /* paper corners are sharper than UI corners */
  padding: clamp(var(--sp-4), 3vw, var(--sp-6));
  box-shadow: var(--shadow-sheet);
}
.sheet__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
  padding-bottom: var(--sp-3); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--rule);
}
.sheet__title {
  font-family: var(--font-display); font-size: var(--step-0);
  font-weight: 650; letter-spacing: -.01em;
}
.sheet__rule {
  font-size: .74rem; color: var(--muted);
  display: flex; gap: .4rem; align-items: center;
}
.sheet .puzzle { box-shadow: none; border-color: var(--rule-strong); max-width: none; }
.sheet .wordlist { margin-top: var(--sp-4); }

/* --------------------------------------------------------------- hero */

/* Show the thing, do not describe it. The preview carries more conviction than
   any headline, and it is the only image on the page — so it costs nothing. */
.hero {
  display: grid; gap: var(--sp-6);
  padding-block: var(--sp-7) var(--sp-6);
  align-items: center;
}
@media (min-width: 56rem) {
  .hero { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: var(--sp-8); }
  .hero__copy { max-width: 26rem; }
}
.hero__copy { display: flex; flex-direction: column; gap: var(--sp-4); }
.hero h1 { font-size: var(--step-4); max-width: 15ch; }
.hero .lede { font-size: var(--step-1); }

.hero__sheet { position: relative; }
/* A second sheet peeking out behind: the stack reads as "there are many of these"
   without needing a second image. */
.hero__sheet::before {
  content: ""; position: absolute; inset: 1.1rem -0.6rem -0.9rem 1.1rem;
  background: var(--surface-sunken); border: 1px solid var(--rule);
  border-radius: 4px; z-index: -1;
}

/* --------------------------------------------------------------- rhythm */

.section { padding-block: var(--sp-7); }
.section + .section { padding-top: 0; }
.section__head { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-5); }
.section__head h2 { letter-spacing: -.02em; }

.section-title::after { background: linear-gradient(to right, var(--rule), transparent); }

/* Cards sit flatter now; the border does the work and the hover does the rest. */
.card { box-shadow: none; }
.tile { box-shadow: none; }
.tile:hover, .tile:focus-visible { box-shadow: var(--shadow-2); border-color: var(--rule-strong); }

.divider { background: linear-gradient(to right, var(--rule), transparent); }

/* --------------------------------------------------------------- pin studio */

.pin-grid { display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); }
.pin-card {
  display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: var(--sp-4);
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: var(--sp-4);
}
.pin-card__img { width: 100%; aspect-ratio: 2/3; object-fit: contain; border: 1px solid var(--rule); border-radius: 4px; background: #fff; }
.pin-card__body { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.pin-card__title { font-weight: 650; font-size: var(--step--1); line-height: 1.35; }
.pin-card__text { font-size: .82rem; color: var(--muted); line-height: 1.5; }
.pin-card .btn { padding: .3rem .6rem; font-size: .76rem; }
.pin-card .meta { font-size: .74rem; word-break: break-all; }

/* --------------------------------------------------------------- math sheet */

.problems { display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: var(--sp-5) var(--sp-4); }
.problem { display: flex; gap: .4rem; align-items: flex-start; }
.problem__n { font-size: .7rem; color: var(--muted); padding-top: .15rem; font-variant-numeric: tabular-nums; }
.problem__sum {
  flex: 1; text-align: right; font-size: 1.02rem; line-height: 1.45;
  font-variant-numeric: tabular-nums;
  border-bottom: 1.5px solid var(--rule-strong); padding-bottom: .2rem;
}
@media (max-width: 34rem) { .problems { grid-template-columns: repeat(3, 1fr); } }

.preview {
  width: 100%; height: auto; border-radius: 4px;
  background: var(--surface);
}
/* The preview is drawn on paper white; in dark mode it needs to stay readable
   without being blinding, so it sits on its own light card. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .preview { background: #fff; padding: .5rem; }
}
:root[data-theme="dark"] .preview { background: #fff; padding: .5rem; }
