/* SilliestDuck — components. Requires tokens.css. Plain classes; no JS. */
.sd-root{background:var(--sd-bg);color:var(--sd-fg);font-family:var(--sd-font-body);font-weight:600;-webkit-font-smoothing:antialiased}
.sd-display{font-family:var(--sd-font-display);font-weight:900;letter-spacing:-.04em;line-height:.95}
.sd-eyebrow{font-family:var(--sd-font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.16em;color:var(--sd-fg-2)}
/* links: ink with a 2px underline, fg-2 on hover. Beak orange is under 3:1 on cream, so it is never a text colour; .sd-link makes a button look like one. */
:where(a:not(.sd-btn)),.sd-link{color:var(--sd-fg);font-weight:800;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}
:where(a:not(.sd-btn)):hover,.sd-link:hover{color:var(--sd-fg-2)}
.sd-link{appearance:none;background:none;border:0;padding:0;margin:0;font:inherit;cursor:pointer}

/* wordmark: "silliest" in fg, "duck" in beak orange. Always with the duck mark. */
.sd-wordmark{display:inline-flex;align-items:center;gap:12px;font-family:var(--sd-font-display);font-weight:900;letter-spacing:-.033em;line-height:1;color:var(--sd-fg)}
.sd-wordmark b{color:var(--sd-beak);font-weight:900}
.sd-wordmark--stacked{flex-direction:column;gap:4px}

/* button — pill, hard 3px drop shadow, presses down on :active. 44px tall at least: a tap target */
.sd-btn{font-family:var(--sd-font-display);font-weight:800;font-size:14px;min-height:44px;box-sizing:border-box;padding:12px 22px;border-radius:var(--sd-r-pill);border:none;cursor:pointer;text-decoration:none;box-shadow:var(--sd-shadow-btn);background:var(--sd-fg);color:var(--sd-bg);transition:transform .08s,box-shadow .08s;display:inline-flex;align-items:center;gap:6px}
.sd-btn:hover{transform:translateY(-1px)}
.sd-btn:active{transform:translateY(3px);box-shadow:0 0 0 transparent}
.sd-btn:focus-visible{outline:3px solid var(--sd-sky-deep);outline-offset:3px}
/* inactive: same language as the locked card. Dashed fg-2 outline, no fill, no shadow, no opacity (keeps the label above 4.5:1). */
.sd-btn:disabled,.sd-btn[aria-disabled="true"]{background:transparent;color:var(--sd-fg-2);border:var(--sd-border-w) dashed var(--sd-fg-2);box-shadow:none;cursor:not-allowed;transform:none}
.sd-btn--accent{background:var(--sd-accent);color:var(--sd-on-accent);box-shadow:0 3px 0 var(--sd-accent-deep)}
.sd-btn--yolk{background:var(--sd-yolk);color:var(--sd-ink);box-shadow:0 3px 0 var(--sd-yolk-deep)}
.sd-btn--berry{background:var(--sd-berry);color:#fff;box-shadow:0 3px 0 var(--sd-berry-deep)}
.sd-btn--pond{background:var(--sd-pond);color:var(--sd-ink);box-shadow:0 3px 0 var(--sd-pond-deep)}
.sd-btn--accent-2{background:var(--sd-accent-2);color:var(--sd-on-accent-2);box-shadow:0 3px 0 var(--sd-accent-2-deep)}
.sd-btn--ghost{background:var(--sd-surface);color:var(--sd-fg);border:var(--sd-border-w) solid var(--sd-line);box-shadow:var(--sd-shadow-ghost)}
[data-theme="dark"] .sd-btn--ghost{background:transparent}
/* small: 28px tall (the height of .sd-badge, so the two line up in a row), no shadow; an invisible 44px strip keeps the tap target */
.sd-btn--sm{font-size:12px;min-height:28px;padding:6px 12px;box-shadow:none;position:relative}
.sd-btn--sm::before{content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%)}
/* round icon button (back, level grid). 48px = comfortable tap target; combine with --ghost */
.sd-btn--icon{width:48px;height:48px;padding:0;justify-content:center;border-radius:50%}

/* chip — uppercase label on an accent fill; ink text always */
.sd-chip{display:inline-block;font-family:var(--sd-font-display);font-weight:800;font-size:11px;padding:5px 11px;border-radius:var(--sd-r-pill);background:var(--sd-pond);color:var(--sd-ink);text-transform:uppercase;letter-spacing:.07em}
.sd-chip--accent{background:var(--sd-accent);color:var(--sd-on-accent)}
.sd-chip--accent-2{background:var(--sd-accent-2);color:var(--sd-on-accent-2)}
.sd-chip--yolk{background:var(--sd-yolk)}.sd-chip--berry{background:var(--sd-berry)}.sd-chip--sky{background:var(--sd-sky)}

/* card — 2px ink border, 22px radius, 6px hard shadow. The shadow token stays a quiet shadow in both themes; only --accent / --accent-2 cards carry a coloured underline. */
.sd-card{background:var(--sd-surface);color:var(--sd-fg);border:var(--sd-border-w) solid var(--sd-line);border-radius:var(--sd-r-card);padding:18px;box-shadow:var(--sd-shadow-card);position:relative}
/* feature card: the game accent as a hard underline (daily, win modal) */
.sd-card--accent{box-shadow:0 6px 0 var(--sd-accent)}
/* secondary-accent card (tutorial / learning, completed) */
.sd-card--accent-2{box-shadow:0 6px 0 var(--sd-accent-2)}
/* small card for dense grids (worlds, archive dates): inset radius, 12px padding, the 4px shadow (accent underlines shrink to match) */
.sd-card--sm{border-radius:var(--sd-r-inset);padding:12px;box-shadow:var(--sd-shadow-card-sm)}
.sd-card--sm.sd-card--accent{box-shadow:0 4px 0 var(--sd-accent)}
.sd-card--sm.sd-card--accent-2{box-shadow:0 4px 0 var(--sd-accent-2)}
/* a card that is a button: lifts onto an accent underline on hover, presses on :active (accent-2 cards keep their colour) */
.sd-card--interactive{cursor:pointer;transition:transform .08s,box-shadow .08s}
.sd-card--interactive:hover{transform:translateY(-2px);box-shadow:0 6px 0 var(--sd-accent)}
.sd-card--interactive:active{transform:translateY(2px);box-shadow:0 2px 0 var(--sd-accent)}
.sd-card--interactive.sd-card--accent-2:hover{box-shadow:0 6px 0 var(--sd-accent-2-deep)}
.sd-card--interactive.sd-card--accent-2:active{box-shadow:0 2px 0 var(--sd-accent-2)}
.sd-card--interactive:focus-visible{outline:3px solid var(--sd-sky-deep);outline-offset:3px}
/* locked card: still a card, still readable, just inactive. Dashed fg-2 border, no shadow, no opacity (opacity pulls the text under 4.5:1). */
.sd-card--locked{background:transparent;border-style:dashed;border-color:var(--sd-fg-2);box-shadow:none;color:var(--sd-fg-2);cursor:not-allowed}
.sd-card--locked:hover,.sd-card--locked:active{transform:none;box-shadow:none}
.sd-card__title{font-family:var(--sd-font-display);font-weight:900;font-size:28px;letter-spacing:-.03em}
.sd-card__hint{font-size:13px;font-weight:700;line-height:1.4;margin:0}
.sd-card--locked .sd-card__title{color:var(--sd-fg-2)}
.sd-card--locked .sd-card__hint{color:var(--sd-fg)}
.sd-lock{width:24px;height:24px;color:var(--sd-fg-2)}
/* completion badge (✓ on a finished world) */
.sd-badge{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--sd-accent-2);color:var(--sd-on-accent-2);font-weight:900}
.sd-inset{background:var(--sd-bg);border-radius:var(--sd-r-inset);padding:14px}
.sd-card__duck{position:absolute;top:-22px;right:14px}
/* mascot host: the SVG fills the host, and the host is sized by --sd-duck-size (Duck.jsx sets it from `size`), so any CSS rule can resize a duck */
.sd-duck-host{display:inline-flex;line-height:0;width:var(--sd-duck-size,48px);height:var(--sd-duck-size,48px)}
.sd-duck-host>.sd-duck{width:100%;height:100%}
/* sleeping duck + floating z's: wrap the duck in .sd-zzz and add three <i>z</i>. Offsets and sizes are for a 44px duck;
   set --sd-zzz-scale (= size / 44) for other sizes. The z's inherit the wrapper's colour (fg-2 by default). */
.sd-zzz{position:relative;display:inline-flex;line-height:0;color:var(--sd-fg-2);--sd-zzz-scale:1}
.sd-zzz i{position:absolute;font-family:var(--sd-font-display);font-weight:900;font-style:normal;line-height:1;pointer-events:none;font-size:calc(12px * var(--sd-zzz-scale));left:calc(38px * var(--sd-zzz-scale));top:calc(-4px * var(--sd-zzz-scale));animation:sd-zzz 2.4s ease-in-out infinite}
.sd-zzz i:nth-of-type(2){font-size:calc(9px * var(--sd-zzz-scale));left:calc(48px * var(--sd-zzz-scale));top:calc(-12px * var(--sd-zzz-scale));animation-delay:.8s}
.sd-zzz i:nth-of-type(3){font-size:calc(7px * var(--sd-zzz-scale));left:calc(56px * var(--sd-zzz-scale));top:calc(-20px * var(--sd-zzz-scale));animation-delay:1.6s}
@keyframes sd-zzz{0%,100%{opacity:.35;transform:translateY(0)}50%{opacity:1;transform:translateY(-3px)}}
@media (prefers-reduced-motion:reduce){.sd-zzz i{animation:none;opacity:1}}

/* HUD — in-game header bar */
.sd-hud{display:flex;justify-content:space-between;align-items:center;gap:12px;background:var(--sd-surface-2);border:var(--sd-border-w) solid var(--sd-line);border-radius:var(--sd-r-card);padding:12px 18px}
.sd-hud__title{display:flex;align-items:center;gap:10px;font-family:var(--sd-font-display);font-weight:900;font-size:18px;letter-spacing:-.03em}
/* in-game header, one row at every width: back (.sd-hud__back) | the status chip, optionally under a title (.sd-hud__mid) | one action (.sd-hud__actions).
   Two equal icon buttons keep the chip centred; a wordmark on the left pushed the action off on narrow screens, and the ← is
   always the way out. No card shadow: it's chrome. */
.sd-hud--center{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 12px}
.sd-hud--center .sd-hud__mid{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0}
.sd-hud--center .sd-hud__title{font-size:22px}
.sd-hud--center .sd-chip{white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.sd-hud--center .sd-hud__back{justify-self:start}
.sd-hud--center .sd-hud__actions{justify-self:end}
.sd-row{display:flex;gap:8px;align-items:center}

/* input */
.sd-label{font-family:var(--sd-font-display);font-weight:800;font-size:13px;margin-bottom:6px;display:block}
.sd-input{width:100%;box-sizing:border-box;padding:12px 16px;border-radius:var(--sd-r-inset);border:var(--sd-border-w) solid var(--sd-line);background:var(--sd-surface);color:var(--sd-fg);font-family:var(--sd-font-display);font-weight:800;font-size:18px}
.sd-input:focus{outline:3px solid var(--sd-sky-deep);outline-offset:2px}

/* toggle — use on <input type="checkbox" class="sd-toggle"> */
.sd-toggle{appearance:none;width:48px;height:28px;border-radius:var(--sd-r-pill);background:var(--sd-rule);border:var(--sd-border-w) solid var(--sd-line);position:relative;cursor:pointer;margin:0;transition:background .15s}
.sd-toggle::after{content:"";position:absolute;left:2px;top:1px;width:22px;height:22px;box-sizing:border-box;border-radius:50%;background:var(--sd-paper);border:var(--sd-border-w) solid var(--sd-ink);transition:left .15s}
.sd-toggle:checked{background:var(--sd-accent-2)}.sd-toggle:checked::after{left:20px}

/* game tiles (board cells): radius scales with the cell, lit tiles get a hard inset bottom edge so the grid never shifts. Off tiles have no edge. */
.sd-tile{aspect-ratio:1;border-radius:var(--sd-r-tile);background:var(--sd-tile-off);transition:background .12s,box-shadow .12s,transform .08s}
.sd-tile--on{background:var(--sd-accent);box-shadow:inset 0 calc(var(--sd-tile-edge) * -1) 0 var(--sd-accent-deep)}
.sd-tile--piece{background:var(--sd-accent-2);box-shadow:inset 0 calc(var(--sd-tile-edge) * -1) 0 var(--sd-accent-2-deep)}
.sd-tile--ghost{background:var(--sd-accent-2);opacity:.35}
/* drop preview: the cells a held piece would cover. Sky is the one palette colour that is neither lit (accent) nor piece (accent-2) and reads on both grounds; berry when the drop is not allowed. Board state, so the one-accent rule for buttons and cards does not apply. */
.sd-tile--preview{background:var(--sd-sky);box-shadow:inset 0 calc(var(--sd-tile-edge) * -1) 0 var(--sd-sky-deep)}
.sd-tile--preview-invalid{background:var(--sd-berry);box-shadow:inset 0 calc(var(--sd-tile-edge) * -1) 0 var(--sd-berry-deep)}
.sd-tile--sm{--sd-tile-edge:2px}
.sd-board{display:grid;gap:8px;padding:18px;background:var(--sd-surface-2);border-radius:var(--sd-r-card)}
.sd-board--inset{background:var(--sd-bg)}
.sd-letter{display:grid;place-items:center;border-radius:var(--sd-r-tile);border:1.5px solid var(--sd-line);background:var(--sd-surface);color:var(--sd-fg);font-family:var(--sd-font-display);font-weight:900;text-transform:uppercase}

/* modal (win state) */
.sd-modal{text-align:center;padding:32px;overflow:hidden}
/* a <b> in the title is emphasis only: beak orange is under 3:1 on the card, so the title stays one colour */
.sd-modal__title{font-family:var(--sd-font-display);font-weight:900;font-size:40px;letter-spacing:-.04em;margin-top:8px}
.sd-modal__title b{color:inherit}
.sd-modal__sub{font-size:14px;color:var(--sd-fg-2);margin-top:4px}
