/* Little Planets wears CozyUI, the hand-drawn kit in ../cozyui rebuilt from the concept art in
   references/. Three layers, and a rule only ever reads the middle one: the paint box lives in
   src/palette.js and arrives as --teal-500 and friends, this block names the roles, and every
   component below reads the roles. Re-skinning is this block and nothing else. */
@font-face {
  font-family: "Baloo 2"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/baloo2-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Baloo 2"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/baloo2-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Patrick Hand"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/patrick-hand-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Patrick Hand"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/patrick-hand-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Patrick Hand SC"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/patrick-hand-sc-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Patrick Hand SC"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/patrick-hand-sc-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

* { box-sizing: border-box; }
/* The bootstrap exception: these two literals paint the first frame, before src/palette.js has
   injected the paint box. Everything after them goes through a token. */
:root { color-scheme: dark; background: #1a3a63; color: #f4ead3; }
:root {
  /* Surfaces */
  --scene: var(--night-700);
  --surface: var(--teal-500);
  --surface-raised: var(--teal-400);
  --surface-edge: var(--teal-300);
  --surface-light: var(--teal-200);
  --raised-light: color-mix(in srgb, var(--teal-400), #fff 34%);
  --surface-shade: var(--teal-700);
  --well: var(--teal-600);
  --paper: var(--paper-200);
  --paper-alt: var(--paper-300);
  --paper-edge: var(--paper-100);
  --paper-shade: var(--paper-400);
  --glass: var(--night-900);
  /* Cut into a surface */
  --recess: var(--ink-700);
  --recess-deep: var(--ink-900);
  --recess-face: var(--ink-600);
  /* Materials */
  --metal: var(--steel-400);
  --metal-light: var(--steel-300);
  --metal-shade: var(--steel-600);
  --metal-sheen: color-mix(in srgb, var(--steel-300), #fff 55%);
  --timber: var(--wood-500);
  --timber-shade: var(--wood-600);
  --ground: var(--grass-500);
  /* Marks */
  --line: var(--ink-800);
  --line-soft: color-mix(in srgb, var(--ink-800) 45%, transparent);
  --shadow: var(--ink-900);
  --text: var(--ink-800);
  --text-dim: color-mix(in srgb, var(--ink-800) 62%, transparent);
  --text-invert: var(--paper-200);
  --text-invert-dim: color-mix(in srgb, var(--paper-200) 66%, transparent);
  /* Meaning: gold means "press this", and a screen gets one. */
  --accent: var(--gold-500);
  --accent-light: var(--gold-300);
  --accent-shade: var(--gold-600);
  --accent-tan: color-mix(in srgb, var(--gold-600), var(--wood-600) 45%);
  --accent-deep: color-mix(in srgb, var(--gold-600), var(--ink-900) 38%);
  --accent-text: var(--ink-800);
  --success: var(--lime-500);
  --success-light: color-mix(in srgb, var(--lime-500), #fff 45%);
  --success-shade: color-mix(in srgb, var(--lime-500), var(--ink-900) 30%);
  --danger: var(--rose-500);
  --danger-light: color-mix(in srgb, var(--rose-500), #fff 36%);
  --danger-shade: color-mix(in srgb, var(--rose-500), var(--ink-900) 24%);
  --danger-deep: color-mix(in srgb, var(--rose-500), var(--ink-900) 45%);
  --special: var(--violet-500);
  --special-light: var(--violet-300);
  --special-shade: color-mix(in srgb, var(--violet-500), var(--ink-900) 30%);
  --special-deep: color-mix(in srgb, var(--violet-500), var(--ink-900) 55%);
  --sky: var(--sky-300);

  /* Cartoon art has two stroke weights. Resist a third. */
  --line-w: 3px;
  --line-w-thin: 2px;
  --line-w-hair: 1.5px;
  /* Depth: a light band and a shade band inside the shape, a solid ink drop under it. */
  --band-light: 3px;
  --band-shade: 5px;
  --drop: 5px;
  --press: 3px;
  --cel: inset 0 var(--band-light) 0 color-mix(in srgb, #fff 34%, transparent), inset 0 calc(var(--band-shade) * -1) 0 color-mix(in srgb, var(--shadow) 20%, transparent);
  --cel-surface: var(--cel);
  --cel-raised: var(--cel);
  --cel-paper: inset 0 3px 0 var(--paper-edge), inset 0 -5px 0 var(--paper-shade);
  --cel-metal: inset 0 4px 0 var(--metal-light), inset 0 -5px 0 var(--metal-shade);
  --cel-accent: inset 0 3px 0 var(--accent-light), inset 0 -5px 0 var(--accent-shade);
  --cel-danger: inset 0 3px 0 var(--danger-light), inset 0 -5px 0 var(--danger-shade);
  --cel-timber: inset 0 3px 0 color-mix(in srgb, #fff 26%, transparent), inset 0 -5px 0 var(--timber-shade);
  --sunken: inset 0 3px 0 color-mix(in srgb, var(--shadow) 45%, transparent), inset 0 -2px 0 color-mix(in srgb, #fff 14%, transparent);
  --haze: 0 6px 18px color-mix(in srgb, var(--shadow) 45%, transparent);
  --haze-lg: 0 14px 34px color-mix(in srgb, var(--shadow) 52%, transparent);
  --notice-cel: var(--cel-paper);
  /* Knurling and sheen for the one thing made of metal: the instrument hardware. */
  --groove: color-mix(in srgb, var(--shadow) 42%, transparent);
  --ridge: color-mix(in srgb, #fff 35%, transparent);
  --knurl: repeating-linear-gradient(90deg, var(--groove) 0 2px, var(--ridge) 2px 3px, transparent 3px 5px);

  /* Everything is a pebble. Nothing is sharp. */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-xl: 30px;
  --r-pill: 999px;
  --r-hand: 18px 22px 20px 24px;

  /* One physical card, shown at three scales. */
  --card-ratio: 5 / 7;
  --card-full-width: 370px;
  --card-compact-width: 180px;
  --card-thumbnail-width: 72px;

  /* Four voices, no fifth: display shouts the name, ui names a screen or a control, hand is a
     person speaking. Sized in cqi so a screen scales to the screen, not the desktop. */
  --font-display: "Baloo 2", "Trebuchet MS", system-ui, sans-serif;
  --font-ui: "Patrick Hand SC", "Baloo 2", "Trebuchet MS", system-ui, sans-serif;
  --font-hand: "Patrick Hand", "Bradley Hand", cursive;
  --t-display: clamp(33px, 14.5cqi, 74px);
  --t-title: clamp(15px, 4.7cqi, 24px);
  --t-body: clamp(13px, 3.5cqi, 18px);
  --t-label: clamp(11px, 3.1cqi, 15px);
  --t-meta: clamp(9px, 2.6cqi, 13px);
  --t-micro: clamp(8px, 2.2cqi, 11px);
  --track-label: .16em;
  --tilt: -1.2deg;
  --motion-ease: cubic-bezier(.2, .9, .3, 1);
  --motion-bounce: cubic-bezier(.34, 1.56, .64, 1);
  --motion-page: 320ms;
  --motion-panel: 220ms;
  --motion-home: 500ms;
}
html, body { margin: 0; min-height: 100%; overflow: hidden; background: var(--scene, #1a3a63); -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
body { min-height: 100svh; touch-action: none; font-family: var(--font-ui); font-size: var(--t-body); color: var(--text); }
input { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
button, input { font: inherit; }
button { color: inherit; }
button:focus-visible, input:focus-visible { outline: var(--line-w) solid var(--accent); outline-offset: 3px; }
/* src/palette.js paints the paint box onto :root, and until it has there is no --surface and no
   --line to draw with. Rather than show a frame of unfilled chrome, the interface waits and the
   bootstrap sky above stands in for it. */
html:not([data-painted]) #app { visibility: hidden; }
#app { position: relative; width: 100%; height: 100svh; overflow: hidden; background: var(--scene); }
/* The native wrappers hold the same painting over the web view until this page reports that its
   backdrop, fonts and modules are ready. Only the home furniture enters during the dissolve. */
html[data-starting]:not([data-ready]) .home-screen > :not(.home-sky) { opacity: 0; }
html[data-starting][data-ready] .home-screen.is-active .brand { animation: startup-brand-in 700ms 80ms var(--motion-ease) both; }
html[data-starting][data-ready] .home-screen.is-active .home-actions > :nth-child(1) { animation: startup-action-in 620ms 170ms var(--motion-ease) both; }
html[data-starting][data-ready] .home-screen.is-active .home-actions > :nth-child(2) { animation: startup-action-in 620ms 245ms var(--motion-ease) both; }
html[data-starting][data-ready] .home-screen.is-active .home-actions > :nth-child(3) { animation: startup-action-in 620ms 320ms var(--motion-ease) both; }
@keyframes startup-brand-in { from { opacity: 0; transform: translateY(-18px); } }
@keyframes startup-action-in { from { opacity: 0; transform: translateY(22px); } }
@media (prefers-reduced-motion: reduce) {
  html[data-starting][data-ready] .home-screen.is-active :is(.brand, .home-actions > *) { animation: none; }
}
/* Every screen is its own container, so the type scale answers to the phone and not to the desktop
   the phone is being previewed on. */
.screen { display: none; position: absolute; inset: 0; overflow: hidden; container-type: inline-size; background: var(--scene); color: var(--text); }
.screen:is(.is-active, .is-transitioning) { display: flex; flex-direction: column; }
.screen.is-transitioning { pointer-events: none; will-change: transform, opacity; }
.screen[data-transition="in-forward"] { z-index: 2; box-shadow: -18px 0 34px color-mix(in srgb, var(--shadow) 38%, transparent); animation: screen-in-forward var(--motion-page) var(--motion-ease) both; }
.screen[data-transition="out-forward"] { z-index: 1; animation: screen-out-forward var(--motion-page) var(--motion-ease) both; }
.screen[data-transition="in-backward"] { z-index: 1; animation: screen-in-backward var(--motion-page) var(--motion-ease) both; }
.screen[data-transition="out-backward"] { z-index: 2; box-shadow: -18px 0 34px color-mix(in srgb, var(--shadow) 38%, transparent); animation: screen-out-backward var(--motion-page) var(--motion-ease) both; }
@keyframes screen-in-forward { from { opacity: .76; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } }
@keyframes screen-out-forward { from { opacity: 1; transform: translateX(0); } to { opacity: .74; transform: translateX(-16%); } }
@keyframes screen-in-backward { from { opacity: .74; transform: translateX(-16%); } to { opacity: 1; transform: translateX(0); } }
@keyframes screen-out-backward { from { opacity: 1; transform: translateX(0); } to { opacity: .76; transform: translateX(100%); } }

/* Home is a stage rather than another page: its sign and menu clear independently, then the next
   screen's wooden header drops into place before the working area settles underneath it. */
.home-screen[data-transition="out-forward"] { animation: home-shell-out var(--motion-home) var(--motion-ease) both; }
.screen[data-transition="in-forward"][data-transition-from="home"] { animation: destination-shell-in var(--motion-home) var(--motion-ease) both; }
.screen[data-transition="out-backward"][data-transition-to="home"] { animation: destination-shell-out var(--motion-home) var(--motion-ease) both; }
.home-screen[data-transition="in-backward"] { animation: home-shell-in var(--motion-home) var(--motion-ease) both; }

.home-screen[data-transition="out-forward"] .brand { animation: home-brand-out 340ms var(--motion-ease) both; }
.home-screen[data-transition="out-forward"] .home-actions > :nth-child(1) { animation: home-action-out 320ms 0ms var(--motion-ease) both; }
.home-screen[data-transition="out-forward"] .home-actions > :nth-child(2) { animation: home-action-out 320ms 35ms var(--motion-ease) both; }
.home-screen[data-transition="out-forward"] .home-actions > :nth-child(3) { animation: home-action-out 320ms 70ms var(--motion-ease) both; }
.home-screen[data-transition="in-backward"] .brand { animation: home-brand-in 390ms 55ms var(--motion-ease) both; }
.home-screen[data-transition="in-backward"] .home-actions > :nth-child(1) { animation: home-action-in 360ms 105ms var(--motion-ease) both; }
.home-screen[data-transition="in-backward"] .home-actions > :nth-child(2) { animation: home-action-in 360ms 70ms var(--motion-ease) both; }
.home-screen[data-transition="in-backward"] .home-actions > :nth-child(3) { animation: home-action-in 360ms 35ms var(--motion-ease) both; }

.screen[data-transition-from="home"] > .topbar { transform-origin: 50% 0; animation: topbar-roll-in 410ms 25ms var(--motion-bounce) both; }
.screen[data-transition-to="home"] > .topbar { transform-origin: 50% 0; animation: topbar-roll-out 280ms var(--motion-ease) both; }
.telescope-screen[data-transition-from="home"] .telescope-frame { animation: destination-focus-in 360ms 80ms var(--motion-ease) both; }
.telescope-screen[data-transition-from="home"] .telescope-console { animation: destination-rise-in 360ms 120ms var(--motion-ease) both; }
.telescope-screen[data-transition-to="home"] .telescope-workbench { animation: destination-body-out 280ms var(--motion-ease) both; }
.album-screen[data-transition-from="home"] .album-summary { animation: destination-rise-in 320ms 80ms var(--motion-ease) both; }
.album-screen[data-transition-from="home"] :is(.album-grid, .empty-album, .album-goals) { animation: destination-rise-in 360ms 125ms var(--motion-ease) both; }
.album-screen[data-transition-to="home"] > :not(.topbar) { animation: destination-body-out 280ms var(--motion-ease) both; }
.workshop-screen[data-transition-from="home"] .workshop-stage { animation: destination-rise-in 380ms 95ms var(--motion-ease) both; }
.workshop-screen[data-transition-to="home"] .workshop-stage { animation: destination-body-out 280ms var(--motion-ease) both; }

@keyframes home-shell-out { from { opacity: 1; transform: scale(1); } to { opacity: .28; transform: scale(1.025); } }
@keyframes home-shell-in { from { opacity: .28; transform: scale(1.025); } to { opacity: 1; transform: scale(1); } }
@keyframes destination-shell-in { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: scale(1); } }
@keyframes destination-shell-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(.985); } }
@keyframes home-brand-out { to { opacity: 0; transform: translate(-42px, -8px) rotate(-1.4deg); } }
@keyframes home-brand-in { from { opacity: 0; transform: translate(-42px, -8px) rotate(-1.4deg); } }
@keyframes home-action-out { to { opacity: 0; transform: translate(54px, 5px) rotate(.65deg); } }
@keyframes home-action-in { from { opacity: 0; transform: translate(54px, 5px) rotate(.65deg); } }
@keyframes topbar-roll-in {
  from { opacity: 0; transform: translateY(-105%) rotate(-1.4deg); }
  72% { opacity: 1; transform: translateY(5px) rotate(.3deg); }
  to { opacity: 1; transform: translateY(0) rotate(0); }
}
@keyframes topbar-roll-out { to { opacity: 0; transform: translateY(-105%) rotate(-1deg); } }
@keyframes destination-focus-in { from { opacity: 0; transform: translateY(16px) scale(.94) rotate(-.4deg); } }
@keyframes destination-rise-in { from { opacity: 0; transform: translateY(28px); } }
@keyframes destination-body-out { to { opacity: 0; transform: translateY(22px); } }
.eyebrow { color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; border: 0; clip-path: inset(50%); white-space: nowrap; }
button { border: 0; cursor: pointer; }
/* Patrick Hand and Patrick Hand SC have one weight apiece: asking for bold smears them. A
   voice gets its emphasis from size, tracking and colour instead. */
b, strong { font-weight: 400; }


/* One gold thing per screen: --accent means "press this". */
.primary-button { position: relative; display: flex; align-items: center; justify-content: center; gap: 13px; min-height: 58px; padding: 9px 22px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--accent); color: var(--accent-text); font-family: var(--font-ui); font-size: var(--t-label); text-transform: uppercase; letter-spacing: var(--track-label); box-shadow: var(--cel-accent), 0 var(--drop) 0 var(--shadow); transition: translate .12s, box-shadow .12s; }
.primary-button:active { translate: 0 var(--press); box-shadow: var(--cel-accent), 0 1px 0 var(--shadow); }
.primary-button:disabled { opacity: .45; filter: saturate(.4); cursor: default; }
.primary-button:disabled:active { translate: none; box-shadow: var(--cel-accent), 0 var(--drop) 0 var(--shadow); }
.primary-button b, .primary-button small { display: block; text-align: left; }
.primary-button b { font-weight: 400; }
.primary-button small { margin-top: 3px; font-size: var(--t-meta); letter-spacing: .1em; opacity: .74; }
.primary-button.compact { min-height: 50px; padding-inline: 18px; }
.button-icon { font-size: 27px; line-height: 1; }
.icon-button { position: relative; display: grid; place-items: center; width: 44px; height: 44px; border: var(--line-w) solid var(--line); border-radius: var(--r-sm); background: var(--paper); color: var(--text); font-size: 26px; line-height: 1; box-shadow: var(--cel-paper), 0 3px 0 var(--shadow); }
.icon-button:active { translate: 0 2px; box-shadow: var(--cel-paper), 0 1px 0 var(--shadow); }
/* A screen header is a plank of wood with the title burnt into it. */
.topbar { position: sticky; top: 0; z-index: 5; display: grid; flex: none; grid-template-columns: 46px 1fr auto; align-items: center; gap: 12px; min-height: 80px; padding: max(14px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left)); border-bottom: var(--line-w) solid var(--line); background: repeating-linear-gradient(92deg, color-mix(in srgb, var(--timber-shade) 22%, transparent) 0 2px, transparent 2px 26px), var(--timber); color: var(--text); box-shadow: var(--cel-timber); }
/* The plank's upper ink edge lives just outside the scrollport until an iOS pull-down reveals it. */
.topbar::before { content: ""; position: absolute; top: calc(-1 * var(--line-w)); right: 0; left: 0; border-top: var(--line-w) solid var(--line); }
.topbar-leading { grid-column: 1; }
.topbar-title { grid-column: 2; min-width: 0; }
.topbar-trailing { grid-column: 3; justify-self: end; }
.topbar-title > span, .topbar-title > strong { display: block; }
.topbar-title > strong { margin-top: 3px; font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; letter-spacing: .05em; }
.telescope-screen .topbar { grid-template-columns: 46px 1fr; }
.telescope-screen .topbar-leading { grid-column: 1; }
.telescope-screen .topbar-title { grid-column: 2; }
.telescope-screen .topbar:has(.sky-check-open:not([hidden])) { grid-template-columns: 46px 1fr 46px; }
.sky-check-open { color: var(--success-shade); }
.sky-check-open[hidden] { display: none; }

/* The home screen is the painting: night sky, a moon, a green hill, and the menu resting on it. */
.home-screen { color: var(--text-invert); overflow: hidden auto; padding-block: max(clamp(16px, 4.3svh, 32px), env(safe-area-inset-top)) max(clamp(14px, 3.5svh, 26px), env(safe-area-inset-bottom)); padding-inline: max(24px, env(safe-area-inset-left)) max(24px, env(safe-area-inset-right)); background: linear-gradient(var(--night-800) 0 18%, var(--night-600) 62%, var(--night-700) 100%); }
.home-screen::before { content: ""; flex: 0 1 6vh; }
/* The hill: an ink horizon bowed like a pen would bow it. */
.home-screen::after { content: ""; position: absolute; inset: 54% -12% -2%; z-index: 0; border: var(--line-w) solid var(--line); border-bottom: 0; border-radius: 46% 54% 0 0 / 14% 14% 0 0; background: linear-gradient(var(--ground), color-mix(in srgb, var(--ground), var(--shadow) 28%)); }
.home-sky { position: absolute; inset: 0 0 40%; }
.home-sky::after { content: ""; position: absolute; width: 74px; height: 74px; right: 11%; top: 17%; border: var(--line-w) solid var(--line); border-radius: 50%; background: radial-gradient(circle at 62% 66%, color-mix(in srgb, var(--shadow) 16%, transparent) 0 26%, transparent 27%), radial-gradient(circle at 34% 30%, color-mix(in srgb, #fff 30%, transparent) 0 18%, transparent 19%), var(--accent); box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 13%, transparent), 0 0 0 20px color-mix(in srgb, var(--accent) 8%, transparent), 0 0 0 38px color-mix(in srgb, var(--accent) 4%, transparent), 0 0 46px 10px color-mix(in srgb, var(--accent) 22%, transparent); }
.home-sky i { position: absolute; width: 11px; height: 11px; background: var(--accent); clip-path: polygon(50% 0%, 58% 42%, 100% 50%, 58% 58%, 50% 100%, 42% 58%, 0% 50%, 42% 42%); animation: twinkle 4s cubic-bezier(.2, .9, .3, 1) infinite; }
.home-sky i:nth-child(1){left:13%;top:22%;animation-delay:-.4s}.home-sky i:nth-child(2){left:48%;top:13%;animation-delay:-1.9s}.home-sky i:nth-child(3){left:82%;top:48%;animation-delay:-2.7s}.home-sky i:nth-child(4){left:31%;top:52%;animation-delay:-1.1s}.home-sky i:nth-child(5){left:60%;top:39%;animation-delay:-3.3s}
@keyframes twinkle { 0%, 100% { scale: 1; opacity: .9; } 50% { scale: .72; opacity: .45; } }
.brand { z-index: 1; position: relative; margin-block: auto 8px; }
/* A signpost hammered into the hill, not a button on a bar. */
.logout-button { position: absolute; top: 0; right: 0; padding: 8px 14px 10px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--timber-shade) 20%, transparent) 0 2px, transparent 2px 22px), var(--timber); color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); text-transform: uppercase; rotate: -1.5deg; box-shadow: var(--cel-timber), var(--haze); }
.logout-button:active { translate: 0 2px; rotate: -.6deg; }
.brand-mark { color: var(--accent); font-size: clamp(20px, 3.8svh, 28px); }
.brand h1 { margin: 4px 0; color: var(--paper-edge); font-family: var(--font-display); font-weight: 800; font-size: clamp(38px, min(14vw, 7svh), 68px); line-height: .92; letter-spacing: -.01em; text-shadow: 3px 4px 0 color-mix(in srgb, var(--special) 55%, var(--shadow)); }
.brand p { margin: clamp(8px, 2svh, 15px) 0; color: var(--text-invert-dim); font-size: var(--t-label); letter-spacing: .2em; text-transform: uppercase; }
.home-actions { z-index: 2; display: grid; gap: clamp(8px, 1.6svh, 12px); margin-top: auto; }
@media (max-width:959px){
  .brand:has(.contract-hint:not([hidden])){margin-top:100px}
  .brand:has(.goal-hint:not([hidden])){margin-bottom:112px}
}
/* On the hill the menu is rows, not buttons: the featured one is paper, the rest are teal. */
.home-actions .primary-button { justify-content: flex-start; gap: 16px; min-height: clamp(54px, 9svh, 78px); padding: clamp(6px, 1.2svh, 12px) 20px; border-radius: var(--r-lg); background: var(--paper-alt); color: var(--text); box-shadow: var(--cel-paper), var(--haze); }
.home-actions .primary-button:active { box-shadow: var(--cel-paper), 0 1px 0 var(--shadow); }
.home-actions .primary-button .button-icon { position: relative; padding-right: 16px; }
.home-actions .primary-button .button-icon::after { content: ""; position: absolute; right: 0; top: 12%; width: var(--line-w-thin); height: 76%; border-radius: 2px; background: var(--line-soft); }
.home-actions .primary-button b { font-size: var(--t-title); }
.home-actions .secondary-button { min-height: clamp(46px, 7svh, 62px); }
.secondary-button { position: relative; display: flex; align-items: center; gap: 14px; min-height: 52px; padding: 8px 20px; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--surface-raised); color: var(--text); font-family: var(--font-ui); font-size: var(--t-title); text-transform: uppercase; letter-spacing: .05em; box-shadow: var(--cel), var(--haze); transition: translate .12s, box-shadow .12s; }
.secondary-button em { margin-left: auto; min-width: 54px; padding: 3px 10px 4px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-sm); background: var(--recess); color: var(--accent); font-size: var(--t-label); font-style: normal; font-variant-numeric: tabular-nums; text-align: center; letter-spacing: .08em; box-shadow: var(--sunken); }
.secondary-button:active { translate: 0 var(--press); box-shadow: var(--cel), 0 1px 0 var(--shadow); }

/* Developer-only real-sky acceptance sheet, opened by `?sky-check`. It uses the same paper,
   outlines and press response as the game while staying visually outside the player journey. */
.sky-check-dialog { width: min(760px, calc(100% - 24px)); max-height: calc(100% - 24px); padding: 0; overflow: visible; border: 0; background: transparent; color: var(--text); }
.sky-check-dialog::backdrop { background: color-mix(in srgb, var(--glass) 78%, transparent); backdrop-filter: blur(3px); }
.sky-check-sheet { position: relative; max-height: calc(100svh - 24px); padding: 20px; overflow: auto; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--paper); box-shadow: var(--cel-paper), 0 var(--drop) 0 var(--shadow), var(--haze-lg); }
.sky-check-sheet > header { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.sky-check-sheet h2, .sky-check-sheet h3, .sky-check-sheet h4, .sky-check-sheet p { margin: 0; }
.sky-check-sheet h2 { margin-top: 2px; font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; letter-spacing: .05em; }
.sky-check-sheet h3 { font-family: var(--font-ui); font-size: var(--t-label); font-weight: 400; letter-spacing: .05em; }
.sky-check-sheet h4 { margin-top: 14px; font-size: var(--t-meta); font-weight: 400; letter-spacing: var(--track-label); text-transform: uppercase; }
.sky-check-note { margin-top: 14px !important; color: var(--text-dim); font-size: var(--t-body); line-height: 1.35; }
.sky-check-status { display: block; margin-top: 14px; padding: 8px 12px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--recess); color: var(--text); font-size: var(--t-label); font-weight: 400; letter-spacing: .06em; }
.sky-check-status[data-state="pass"] { background: var(--success); }
.sky-check-status[data-state="fail"] { background: var(--danger); color: var(--text-invert); }
.sky-check-issues { margin: 10px 0 0; padding: 9px 12px 9px 28px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: color-mix(in srgb, var(--danger) 20%, var(--paper)); color: var(--danger-deep); }
.sky-check-summary, .sky-check-detail dl { display: grid; gap: 5px; margin: 14px 0 0; }
.sky-check-summary > div, .sky-check-detail dl > div { display: grid; grid-template-columns: minmax(120px, .7fr) minmax(0, 1.7fr); gap: 10px; padding-bottom: 5px; border-bottom: var(--line-w-hair) dashed var(--line-soft); }
.sky-check-summary dt, .sky-check-detail dt { color: var(--text-dim); font-size: var(--t-meta); letter-spacing: .05em; text-transform: uppercase; }
.sky-check-summary dd, .sky-check-detail dd { min-width: 0; margin: 0; overflow-wrap: anywhere; font-size: var(--t-body); }
.sky-check-section { margin-top: 18px; }
.sky-check-route { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.sky-check-route button, .sky-check-results button { position: relative; display: flex; align-items: center; gap: 9px; min-width: 0; padding: 9px 11px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--surface-raised); color: var(--text); font-family: var(--font-body); text-align: left; box-shadow: 0 2px 0 var(--shadow); }
.sky-check-route button:active, .sky-check-results button:active { translate: 0 1px; box-shadow: none; }
.sky-check-route button i { display: grid; flex: 0 0 23px; place-items: center; height: 23px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--success); font-style: normal; }
.sky-check-route button[data-state="fail"] i { background: var(--danger); color: var(--text-invert); }
.sky-check-route button span, .sky-check-route button :is(b, small) { display: block; min-width: 0; }
.sky-check-route button b { font-size: var(--t-body); }
.sky-check-route button small { margin-top: 1px; color: var(--text-dim); font-size: var(--t-meta); }
.sky-check-search { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin-top: 8px; }
.sky-check-search input { min-width: 0; padding: 9px 11px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); outline: 0; background: var(--paper-alt); color: var(--text); font: inherit; box-shadow: var(--sunken); }
.sky-check-search input:focus { box-shadow: inset 0 0 0 var(--line-w-thin) var(--accent), var(--sunken); }
.sky-check-search .secondary-button { min-height: 42px; padding: 5px 14px; border-radius: var(--r-xs); font-size: var(--t-label); }
.sky-check-results { display: grid; gap: 5px; margin-top: 6px; }
.sky-check-results button { width: 100%; font-size: var(--t-body); }
.sky-check-detail { margin-top: 18px; padding: 14px; border: var(--line-w) solid var(--line); border-radius: var(--r-sm); background: var(--paper-alt); box-shadow: var(--cel-paper); }
.sky-check-detail > header p { margin-top: 2px; color: var(--text-dim); font-size: var(--t-meta); overflow-wrap: anywhere; }
.sky-check-detail ul { display: grid; gap: 5px; max-height: 190px; margin: 7px 0 14px; padding: 0; overflow: auto; list-style: none; }
.sky-check-detail li { padding: 6px 8px; border: var(--line-w-thin) solid var(--line-soft); border-radius: var(--r-xs); background: var(--paper); }
.sky-check-detail li :is(span, small) { display: block; }
.sky-check-detail li small { color: var(--text-dim); overflow-wrap: anywhere; }
.sky-check-detail .primary-button { width: 100%; min-height: 48px; }
@media (max-width:599px) {
  .sky-check-route { grid-template-columns: 1fr; }
  .sky-check-summary > div, .sky-check-detail dl > div { grid-template-columns: 1fr; gap: 2px; }
}

.telescope-screen { background: linear-gradient(var(--night-800), var(--night-700) 58%, var(--night-600)); }
.telescope-workbench { --gutter-left: max(16px, env(safe-area-inset-left)); --gutter-right: max(16px, env(safe-area-inset-right)); --scope-ring: 3px; display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; container-type: inline-size; }
.telescope-frame { display: grid; flex: 0 1 calc(100cqw - var(--gutter-left) - var(--gutter-right) + 32px); min-height: 0; padding: calc(16px + var(--scope-ring)) calc(var(--gutter-right) + var(--scope-ring)) calc(16px + var(--scope-ring)) calc(var(--gutter-left) + var(--scope-ring)); container-type: size; }
/* A teal bezel with a light crescent up top and a shade crescent below, holding a night-glass disc.
   The painted sky layers keep the circular crop while readouts can reach beyond the rim. */
.telescope-stage { --bezel: var(--surface); --bezel-light: var(--surface-light); --bezel-sheen: var(--raised-light); --bezel-shade: var(--surface-shade); --grain-opacity: 2.8%; --scope-scanlines: none; --scope-size: min(100cqw, 100cqh); position: relative; flex: none; width: var(--scope-size); height: var(--scope-size); aspect-ratio: 1 / 1; align-self: center; justify-self: center; overflow: visible; border: 8px solid transparent; border-radius: 50%; background: conic-gradient(transparent 0 20deg, var(--bezel-sheen) 20deg 29deg, transparent 29deg 310deg, var(--bezel-light) 310deg 315deg, transparent 315deg) border-box, radial-gradient(circle closest-side at calc(50% + 2px) calc(50% + 2px), transparent 100%, var(--bezel-light) 100%) border-box, radial-gradient(circle closest-side at calc(50% - 1px) calc(50% - 2px), transparent 100%, var(--bezel-shade) 100%) border-box, linear-gradient(var(--glass), var(--glass)) padding-box, var(--bezel); box-shadow: inset 0 0 70px var(--glass), 0 0 0 var(--line-w) var(--line), var(--haze-lg); }
.telescope-stage::before { content: ""; pointer-events: none; position: absolute; z-index: 1; inset: 0; border-radius: 50%; background-image: var(--scope-scanlines), repeating-linear-gradient(43deg, transparent 0 5px, color-mix(in srgb, var(--sky) var(--grain-opacity), transparent) 5px 6px); }
.telescope-stage::after { content: ""; pointer-events: none; position: absolute; inset: 0; border-radius: 50%; box-shadow: inset 0 0 90px 35px var(--glass); }
#sky-canvas { display: block; width: 100%; height: 100%; border-radius: 50%; image-rendering: auto; }
.scope-reticle { --scan-progress: 0%; pointer-events: none; position: absolute; left: 50%; top: 50%; width: 126px; height: 126px; translate: -50% -50%; border: var(--line-w-thin) solid color-mix(in srgb, var(--sky) 80%, transparent); border-radius: 50%; outline: 1px dashed color-mix(in srgb, var(--sky) 45%, transparent); outline-offset: -24px; box-shadow: 0 0 12px color-mix(in srgb, var(--sky) 20%, transparent); }
.scope-reticle::before { content: ""; position: absolute; inset: -15px; border-radius: 50%; background: conic-gradient(from -90deg, var(--accent) var(--scan-progress), color-mix(in srgb, var(--sky) 22%, transparent) 0); mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 0); }
.scope-reticle::after { content: ""; position: absolute; inset: -20px; background: linear-gradient(90deg, transparent calc(50% - .5px), color-mix(in srgb, var(--sky) 85%, transparent) 50%, transparent calc(50% + .5px)), linear-gradient(transparent calc(50% - .5px), color-mix(in srgb, var(--sky) 85%, transparent) 50%, transparent calc(50% + .5px)); }
.scope-readout { position: absolute; left: 50%; bottom: 10%; translate: -50%; z-index: 3; text-align: center; text-shadow: 0 2px 0 var(--glass); }
.scope-readout span, .scope-readout b { display: block; }
.scope-readout span { color: var(--sky); font-size: var(--t-label); letter-spacing: var(--track-label); }
.scope-readout b { margin-top: 5px; color: var(--text-invert); font-size: var(--t-title); font-weight: 400; letter-spacing: .05em; }
/* The console is a teal panel bolted to the bottom of the screen: ink labels, light band at the top,
   and a haze cast upwards so the sky reads as being behind it. */
.telescope-console { z-index: 4; display: flex; flex: 1 0 var(--console-height, auto); flex-direction: column; padding: 13px var(--gutter-right) max(18px, env(safe-area-inset-bottom)) var(--gutter-left); border-top: var(--line-w) solid var(--line); background: var(--surface); color: var(--text); box-shadow: inset 0 var(--band-light) 0 var(--surface-light), 0 -6px 18px color-mix(in srgb, var(--shadow) 40%, transparent); }
.signal-readout { display: grid; grid-template-columns: auto 1fr 65px; align-items: center; gap: 10px; margin-bottom: 16px; color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); }
/* A row of lamps in a dark channel: the fill lights them, the dividers over it cut them apart. */
.signal-readout div { position: relative; height: 12px; overflow: hidden; padding: 2px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--recess-deep); box-shadow: var(--sunken); }
.signal-readout div::after { content: ""; pointer-events: none; position: absolute; inset: 0; background: repeating-linear-gradient(90deg, transparent 0 9px, color-mix(in srgb, var(--recess-deep) 88%, transparent) 9px 13px); }
.signal-readout i { display: block; width: 0; height: 100%; background: var(--success); box-shadow: inset 0 var(--line-w-hair) 0 var(--success-light); transition: width .15s; }
.signal-readout b { color: var(--text); font-size: var(--t-meta); font-weight: 400; text-align: right; }
/* The bank has four named pieces and four explicit phone states. JavaScript writes data-focus when
   one opens; the layout no longer has to infer application state from descendants or source order. */
.control-bank { --dial-scale: 1; --track: 30px; --drum: 30px; --dial-size: 180px; display: grid; flex: 1 1 auto; grid-template-columns: repeat(6, minmax(0, 1fr)); grid-template-rows: auto minmax(0, 1fr); grid-template-areas: "zoom zoom zoom zoom focus focus" "azimuth azimuth azimuth altitude altitude altitude"; gap: 10px 12px; }
.control-bank[data-focus="zoom"] { grid-template-areas: "zoom zoom zoom zoom zoom zoom" "azimuth azimuth altitude altitude focus focus"; }
.control-bank[data-focus="azimuth"] { grid-template-areas: "zoom zoom zoom zoom focus focus" "azimuth azimuth azimuth azimuth altitude altitude"; }
.control-bank[data-focus="altitude"] { grid-template-areas: "zoom zoom zoom zoom focus focus" "azimuth azimuth altitude altitude altitude altitude"; }
.control-assembly { min-width: 0; }
.control-bank [data-control] { touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; cursor: grab; }
.control-bank [data-control]:focus-visible { outline: var(--line-w) solid var(--accent); outline-offset: var(--focus-offset, 2px); }
.control-bank [data-control].is-turning { cursor: grabbing; filter: brightness(1.07); }
[data-control-group="zoom"] { grid-area: zoom; }
[data-control-group="focus"] { grid-area: focus; }
[data-control-group="azimuth"] { grid-area: azimuth; }
[data-control-group="altitude"] { grid-area: altitude; }
.dial-assembly { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: var(--label-height, auto) minmax(0, 1fr); gap: 4px 7px; text-align: center; }
.control-label, .control-assembly > b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.control-label, .focus-lamps li[data-lamp="sharp"]::after { width: max-content; padding: 1px var(--chip-padding, 8px) 2px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: var(--accent); color: var(--accent-text); letter-spacing: var(--track-label); box-shadow: 0 2px 0 color-mix(in srgb, var(--shadow) 35%, transparent); }
.control-label { font-size: var(--t-meta); text-transform: uppercase; }
.control-assembly > b { color: var(--text); font-size: var(--t-meta); font-weight: 400; line-height: 1.2; font-variant-numeric: tabular-nums; }
.dial-assembly > .control-label { grid-area: 1 / 1; justify-self: end; }
.dial-assembly > b { grid-area: 1 / 2; justify-self: start; }
.dial-assembly:not(.is-focused) > .control-label { grid-column: 1 / -1; justify-self: center; }
.dial-assembly:not(.is-focused) > b { display: none; }
.control-dial { --outline: clamp(2px, 2.6cqmin, 4px); --rim: clamp(2px, 3.4cqmin, 5px); position: relative; grid-column: 1 / -1; align-self: start; justify-self: center; width: min(100%, calc(var(--dial-size) * var(--dial-scale))); aspect-ratio: 1; container-type: size; }
.control-dial::before { content: ""; position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 clamp(3px, 4cqmin, 6px) 0 var(--shadow); }
.control-wheel, .fine-knob { --focus-offset: 3px; position: absolute; display: grid; place-items: center; border: var(--outline) solid var(--line); border-radius: 50%; }
.control-wheel::before, .fine-knob::before, .control-wheel::after, .fine-knob::after { content: ""; pointer-events: none; position: absolute; border-radius: 50%; }
/* The fixed circular rims stay sharp at high DPI while the detents and index marks turn inside them. */
.control-wheel::after, .fine-knob::after { rotate: var(--rotation, 0rad); }
.control-wheel { inset: 0; background: var(--metal); }
.control-wheel::before { inset: 0; background: conic-gradient(transparent 0 20deg, var(--metal-sheen) 20deg 33deg, transparent 33deg 312deg, var(--metal-light) 312deg 320deg, transparent 320deg); box-shadow: inset clamp(2px, 3cqmin, 5px) clamp(4px, 6cqmin, 9px) 0 var(--metal-light), inset 0 calc(clamp(4px, 7cqmin, 10px) * -1) 0 var(--metal-shade); }
.control-wheel::after { inset: 0; background: conic-gradient(from -2deg, var(--accent) 0 4deg, transparent 4deg), repeating-conic-gradient(from calc(var(--detent) / 2 - .7deg), var(--groove) 0 1.1deg, color-mix(in srgb, var(--groove) 45%, transparent) 1.1deg 1.4deg, var(--ridge) 1.4deg 2.1deg, color-mix(in srgb, var(--ridge) 35%, transparent) 2.1deg 2.4deg, transparent 2.4deg var(--detent)); mask: radial-gradient(closest-side, transparent calc(58% - 1px), #000 58% 87%, transparent calc(87% + 1px)); }
/* The fine knob is the face cut into the coarse ring: a dark dish, lit from below like a bowl. */
.fine-knob { left: 50%; top: 50%; width: 52%; aspect-ratio: 1; translate: -50% -50%; background: var(--recess-face); box-shadow: inset 0 0 0 var(--rim) var(--metal-light), inset 0 0 0 calc(var(--rim) + clamp(1.5px, 1.8cqmin, 3px)) var(--line); }
.fine-knob::before, .fine-knob::after { inset: clamp(3.5px, 5.2cqmin, 8px); }
.fine-knob::before { box-shadow: inset calc(clamp(3px, 5cqmin, 8px) * -1) calc(clamp(3px, 5cqmin, 8px) * -1) 0 color-mix(in srgb, var(--recess-face), var(--metal-light) 26%), inset clamp(1px, 2cqmin, 3px) clamp(2px, 3cqmin, 4px) 0 var(--recess-deep); }
.fine-knob::after { background: conic-gradient(from -4deg, var(--metal-light) 0 8deg, transparent 8deg), repeating-conic-gradient(from calc(var(--detent) / 2 - 1deg), var(--groove) 0 1.65deg, color-mix(in srgb, var(--groove) 45%, transparent) 1.65deg 2deg, var(--ridge) 2deg 3deg, color-mix(in srgb, var(--ridge) 35%, transparent) 3deg 3.4deg, transparent 3.4deg var(--detent)); mask: radial-gradient(closest-side, transparent calc(50% - 1px), #000 50%); }
.has-focused-knob .control-bank { min-height: 0; }
.control-assembly.is-focused > .control-label { font-size: var(--t-label); }
.control-assembly.is-focused > b { font-size: calc(var(--t-label) + 2px); }
.control-bank[data-focus="focus"] { --drum: 100px; }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) { --track: 22px; --drum: 40px; --dial-size: 72px; }
.control-bank[data-focus="azimuth"] [data-control-group="azimuth"], .control-bank[data-focus="altitude"] [data-control-group="altitude"] { --dial-size: 220px; }
.zoom-assembly { --cap: 10px; --rail-handle: 30px; display: grid; grid-template: "label label" auto "track track" auto "ticks ticks" auto / 2fr 1fr; align-content: center; align-items: center; gap: 4px 8px; min-width: 0; }
.zoom-assembly > :is(.control-label, b) { grid-area: label; }
.zoom-assembly > .control-label { justify-self: start; }
.zoom-assembly > b { justify-self: end; }
/* Each instrument brings its own magnification control: the rail, one drum from the 200 mm reflector, a coarse
   and a fine drum on the array. What it does not bring leaves the console, focus order included. */
.zoom-assembly:not([data-zoom-control="rail"]) :is(.rail-track, .rail-ticks), .zoom-assembly[data-zoom-control="rail"] :is(.zoom-drum, .zoom-gauge), .zoom-assembly:not([data-zoom-control="drums"]) .zoom-drum[data-precision="fine"] { display: none; }
/* The slot draws its ink outline inset, so the track's border box, padding box and client width are one number. */
.rail-track { grid-area: track; position: relative; height: var(--track); margin: 0 var(--cap); border-radius: var(--r-xs); background: var(--recess); box-shadow: inset 0 0 0 var(--line-w-thin) var(--line), var(--sunken), 0 2px 0 var(--surface-light); }
/* The stops belong to the chassis, not the lever, so the steel reads as the one moving part. */
.rail-track::before, .rail-track::after { content: ""; position: absolute; top: 0; bottom: 0; width: var(--cap); border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--surface-raised); box-shadow: inset 0 var(--band-light) 0 var(--raised-light), inset 0 calc(var(--band-shade) * -1) 0 var(--surface-shade); }
.rail-track::before { left: calc(var(--cap) * -1); }
.rail-track::after { right: calc(var(--cap) * -1); }
/* --travel is 0..1 over the same travel the JS measures: the track's width less the handle's, both ends reachable. */
.rail-handle { position: absolute; left: calc(var(--travel, 0) * (100% - var(--rail-handle))); top: 50%; width: var(--rail-handle); height: min(30px, 100%); translate: 0 -50%; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--knurl), var(--metal); box-shadow: var(--cel-metal); }
.rail-handle::before { content: ""; pointer-events: none; position: absolute; left: 50%; top: 3px; bottom: 3px; width: var(--line-w-thin); translate: -50%; background: var(--accent); box-shadow: 0 0 0 1px var(--line); }
/* The ticks span exactly the handle's travel line, so each mark lands where the handle centre lands. A drum taller
   than the track leaves room under the track, and the ticks tuck up into it. */
.rail-ticks { grid-area: ticks; align-self: start; position: relative; height: 2em; margin: min(0px, (var(--track) - var(--drum)) / 2) calc(var(--cap) + var(--rail-handle) / 2) 0; color: var(--text); font-size: var(--t-meta); letter-spacing: .04em; container-type: inline-size; }
/* A travel too short for five readings keeps every mark and reads only the ends and the middle. */
@container (max-width: 100px) { .rail-ticks span:nth-child(2n) { color: transparent; } }
.rail-ticks span { position: absolute; top: 5px; translate: -50%; }
.rail-ticks span::before { content: ""; position: absolute; left: 50%; top: -5px; width: var(--line-w-thin); height: 3px; translate: -50%; background: var(--line); }
.rail-ticks span:nth-child(1) { left: 0; }
.rail-ticks span:nth-child(2) { left: 25%; }
.rail-ticks span:nth-child(3) { left: 50%; }
.rail-ticks span:nth-child(4) { left: 75%; }
.rail-ticks span:nth-child(5) { left: 100%; }
/* Both edge-on drums share one chassis. Their gradients and index marks merely turn ninety degrees. */
:is(.zoom-drum, .focus-wheel) { position: relative; overflow: hidden; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); box-shadow: var(--sunken), 0 2px 0 var(--surface-light); }
:is(.zoom-drum, .focus-wheel)::after { content: ""; pointer-events: none; position: absolute; background: var(--accent); }
.zoom-drum { grid-row: 2; min-width: 0; height: var(--track); background: repeating-linear-gradient(90deg, var(--groove) 0 2px, var(--ridge) 2px 3px, transparent 3px 5px) calc(var(--turn, 0) * 314.159%) 0 / 5px 100%, linear-gradient(90deg, var(--metal-shade) 0 8%, var(--metal-light) 22%, var(--metal-sheen) 32%, var(--metal) 56%, var(--metal-shade) 92%); }
.zoom-drum[data-precision="fine"] { grid-column: 2; }
.zoom-assembly[data-zoom-control="drum"] .zoom-drum { grid-column: 1 / -1; }
.zoom-drum::after { top: 0; bottom: 0; left: 50%; width: 3px; translate: -50%; box-shadow: -1px 0 0 var(--line), 1px 0 0 var(--line); }
/* A drum has no ends of its own to read, so a quiet gauge under it says how far the instrument still reaches. */
.zoom-gauge { grid-area: ticks; align-self: start; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 6px; margin-top: min(0px, (var(--track) - var(--drum)) / 2); color: var(--text); font-size: var(--t-meta); letter-spacing: .04em; font-variant-numeric: tabular-nums; }
.zoom-gauge i { position: relative; height: 9px; overflow: hidden; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--recess); box-shadow: var(--sunken); }
.zoom-gauge i::before { content: ""; position: absolute; inset: 0 auto 0 0; width: calc(100% * clamp(0, var(--zoom, 0), 1)); border-right: var(--line-w-thin) solid color-mix(in srgb, var(--shadow) 60%, transparent); background: var(--paper-alt); }
.focus-column { display: grid; grid-template-columns: auto auto; align-content: center; justify-content: start; column-gap: 7px; padding-left: 10px; border-left: var(--line-w-thin) solid var(--line); box-shadow: inset 2px 0 0 var(--surface-light); }
.control-bank[data-focus="zoom"] .focus-column { align-content: start; }
/* An edge-on drum scrolls by length, not angle: --turn is in turns, and its 48 detents each advance 6px past the 5px
   ridge pitch, so no two neighbouring detents leave the surface looking alike. */
.focus-wheel { width: 32px; min-height: var(--drum); background: repeating-linear-gradient(0deg, var(--groove) 0 2px, var(--ridge) 2px 3px, transparent 3px 5px), linear-gradient(var(--metal-shade) 0 10%, var(--metal-light) 24%, var(--metal-sheen) 34%, var(--metal) 58%, var(--metal-shade) 86%); background-position: 0 calc(var(--turn, 0) * -288px), 0 0; }
.focus-wheel::after { left: 0; right: 0; top: 50%; height: 3px; translate: 0 -50%; box-shadow: 0 -1px 0 var(--line), 0 1px 0 var(--line); }
.focus-lamps { display: grid; align-content: space-between; gap: 4px; margin: 0; padding: 0; list-style: none; }
.focus-lamps li { display: grid; grid-template-columns: 13px auto; align-items: center; column-gap: 5px; color: var(--text-dim); font-size: var(--lamp-text, var(--t-meta)); letter-spacing: .04em; }
.focus-lamps li::before { content: attr(data-icon); display: grid; place-items: center; height: 13px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--recess); color: var(--text-invert-dim); font-size: var(--t-micro); line-height: 1; box-shadow: var(--sunken); }
.focus-lamps li::after { content: attr(data-label); }
.focus-lamps li[data-lamp="sharp"]::after { --chip-padding: 4px; line-height: 1; }
.focus-lamps li.is-lit { color: var(--text); }
.focus-lamps li.is-lit::before { background: var(--accent); color: var(--accent-text); box-shadow: inset 0 var(--band-light) 0 var(--accent-light); }
.focus-lamps li[data-lamp="sharp"].is-lit { color: var(--text); }
.focus-lamps li[data-lamp="sharp"].is-lit::before { background: var(--success); color: var(--text); box-shadow: inset 0 var(--band-light) 0 var(--success-light); }
/* An opened rail deepens its slot and ring. Its handle grows visually like the desktop selection,
   while its layout box stays fixed so the drag travel does not change under a finger. */
.zoom-assembly.is-focused { --track: 46px; }
.zoom-assembly.is-focused .rail-handle { z-index: 2; scale: 1.2; }
.control-assembly.is-focused :is(.rail-track, .zoom-drum, .focus-wheel) { box-shadow: inset 0 0 0 var(--line-w-thin) var(--accent), var(--sunken), 0 2px 0 var(--surface-light); }
.zoom-assembly.is-focused .rail-ticks { margin-top: 0; font-size: var(--t-label); }
.zoom-assembly.is-focused .zoom-gauge { margin-top: 0; font-size: var(--t-label); }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .zoom-assembly { --cap: 8px; --rail-handle: 24px; row-gap: 2px; }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) :is(.rail-ticks, .zoom-gauge) { font-size: var(--t-micro); }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .focus-column { --lamp-text: var(--t-micro); }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .focus-wheel { width: 26px; }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .focus-lamps { gap: 2px; }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .focus-lamps li { grid-template-columns: 11px auto; }
.control-bank:is([data-focus="azimuth"], [data-focus="altitude"]) .focus-lamps li::before { height: 11px; }
@media (orientation:portrait) {
  .control-bank { --drum: 64px; }
  .zoom-assembly { min-height: max-content; }
  .zoom-assembly :is(.rail-ticks, .zoom-gauge) { margin-top: 0; }
  .dial-assembly.is-focused { --readout-x: calc(125% + 9px); position: relative; display: block; }
  .control-bank[data-focus="altitude"] .dial-assembly.is-focused { --readout-x: calc(-25% - 9px); }
  .dial-assembly.is-focused > :is(.control-label, b) { position: absolute; left: var(--readout-x); z-index: 1; width: max-content; translate: -50%; }
  .dial-assembly.is-focused > .control-label { top: 60%; font-size: calc(var(--t-label) + 1px); }
  .dial-assembly.is-focused > b { top: calc(60% + 28px); font-size: calc(var(--t-label) + 5px); }
  .dial-assembly.is-focused .control-dial { margin-inline: auto; }
}
/* Any viewport wider than it is tall puts the sky beside the instruments, phones included. */
@media (orientation:landscape){
  .telescope-workbench{--console-width:clamp(214px,34cqw,440px);display:grid;grid-template-columns:minmax(0,1fr) var(--console-width);grid-template-rows:1fr}
  .telescope-frame{display:contents}
  .telescope-stage{--scope-size:min(calc(100cqw - var(--console-width) - 48px),calc(100svh - 126px));border-width:min(12px,3cqw)}
  .telescope-console{justify-content:center;padding:clamp(10px,3svh,28px) max(18px,env(safe-area-inset-right)) clamp(10px,3svh,28px) 18px;border-top:0;border-left:var(--line-w) solid var(--line);box-shadow:inset var(--band-light) 0 0 var(--surface-light),-6px 0 18px color-mix(in srgb, var(--shadow) 40%, transparent)}
  .signal-readout{margin-bottom:24px}
  .control-bank{--drum:48px;--dial-size:112px;flex:0 0 auto;gap:10px}
  .has-focused-knob .control-bank{flex:1 1 auto}
  /* The console rail is narrow here, so the lamps keep their arrows and give their words back to the track. */
  .focus-lamps li{column-gap:0;font-size:0}
  .control-bank:is([data-focus="azimuth"],[data-focus="altitude"]){--dial-size:52px}
  .control-bank[data-focus="azimuth"] [data-control-group="azimuth"],.control-bank[data-focus="altitude"] [data-control-group="altitude"]{--dial-size:152px}
}
@media (orientation:landscape) and (max-width:959px){
  .topbar{min-height:44px;padding:max(4px,env(safe-area-inset-top)) max(10px,env(safe-area-inset-right)) 4px max(10px,env(safe-area-inset-left))}
  .topbar-leading{width:34px;height:34px;font-size:22px}
  .topbar .eyebrow{display:none}
  .telescope-screen .topbar-leading{grid-column:1}
  .telescope-screen .topbar-title{grid-column:2}
  .telescope-screen .topbar .eyebrow{display:block}
  .telescope-screen .topbar .telescope-label{display:none}
  .telescope-workbench{--console-width:clamp(238px,calc(34cqw + 24px),464px)}
  .telescope-stage{--scope-size:min(calc(100cqw - var(--console-width) - 48px),calc(100svh - 90px))}
}
/* A console rail 400-440px wide has room to set each label beside its control. */
@media (orientation:landscape) and (min-width:960px){
  .telescope-workbench{--console-width:440px}
  .telescope-console{padding:28px 28px 28px 27px}
  .signal-readout{margin-bottom:24px}
  .control-bank{gap:16px 14px}
  .control-label{font-size:var(--t-label)}
  .focus-lamps li[data-lamp="sharp"]::after{font-size:calc(var(--t-label) - 2pt)}
  .dial-assembly > b{margin-top:3px}
  .control-assembly > b{font-size:var(--t-label)}
  .focus-lamps li{column-gap:5px}
  .focus-column{column-gap:12px}
  .focus-wheel{width:34px}
  .focus-lamps{align-content:center;gap:3px}
  .focus-lamps li{grid-template-columns:14px auto;font-size:var(--lamp-text, var(--t-meta))}
  .focus-lamps li::before{height:14px}
}
/* A phone keeps the compact dials. Larger screens spend their extra room on the physical controls;
   the width cap above still wins when a narrow panel cannot accommodate the preferred scale. */
@media (pointer:coarse) and (min-width:600px) and (min-height:600px){
  .control-bank{--dial-scale:1.1}
}
@media (pointer:fine){
  .control-bank{--dial-scale:1.4}
}
@media (pointer:fine) and (min-width:1440px){
  .control-bank{--dial-scale:1.5}
}
@media (orientation:landscape) and (pointer:coarse){
  .zoom-assembly{min-height:max-content}
  .zoom-assembly :is(.rail-ticks,.zoom-gauge){margin-top:0}
  .dial-assembly.is-focused{--readout-x:calc(125% + 9px);position:relative;display:block}
  .control-bank[data-focus="altitude"] .dial-assembly.is-focused{--readout-x:calc(-25% - 9px)}
  .dial-assembly.is-focused > :is(.control-label,b){position:absolute;left:var(--readout-x);z-index:1;width:max-content;translate:-50%}
  .dial-assembly.is-focused > .control-label{top:60%;font-size:calc(var(--t-label) + 1px)}
  .dial-assembly.is-focused > b{top:calc(60% + 28px);font-size:calc(var(--t-label) + 5px)}
  .dial-assembly.is-focused .control-dial{margin-inline:auto}
}
/* A mouse selects the exact moving part without opening the phone layout around it. */
@media (pointer:fine){
  :is(.control-dial,.rail-handle,.zoom-drum,.focus-wheel).is-selected-control{scale:1.2}
  :is(.rail-handle,.zoom-drum,.focus-wheel).is-selected-control{z-index:2}
  .control-dial.is-selected-control{scale:1.04}
}
/* The scope sizes itself from the space the console leaves, so on short viewports the console compacts instead of growing. */
@media (max-height:700px){
  .telescope-console{padding-top:11px}
  .signal-readout{margin-bottom:8px}
  .control-bank{row-gap:8px}
  .zoom-assembly{row-gap:2px}
  .control-bank{--track:22px}
  .rail-ticks,.zoom-gauge{font-size:var(--t-micro)}
  .control-bank[data-focus="focus"]{--drum:88px}
}

/* Tablets and desktops carry the instruments on a separate CozyUI slab. Phones keep the console
   bolted edge-to-edge in either orientation so their smaller working area is not spent on a frame. */
@media (pointer:fine), (pointer:coarse) and (min-width:600px) and (min-height:600px) {
  .telescope-console.cozy-panel {
    align-self: center;
    max-height: calc(100% - 32px);
    margin: 16px;
    padding: clamp(16px, 3cqi, 28px);
    border: var(--line-w) solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
    box-shadow: var(--cel-surface), var(--haze);
  }
  .telescope-console.cozy-ink--sketch::after {
    content: "";
    position: absolute;
    box-sizing: border-box;
    inset: -3px;
    border: 30px solid transparent;
    border-image: var(--pen) 30 stretch;
    pointer-events: none;
  }
  .telescope-console.cozy-ticks::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-image:
      linear-gradient(72deg, transparent 46%, var(--line) 46% 52%, transparent 52%),
      linear-gradient(72deg, transparent 46%, var(--line) 46% 52%, transparent 52%);
    background-repeat: no-repeat;
    background-position: 14% 86%, 78% 12%;
    background-size: 7px 11px;
    opacity: .5;
    pointer-events: none;
  }
}

/* On unusually tall portrait screens the instruments keep their natural height at the bottom.
   The spare room stays in the sky instead of stretching the console into an empty teal slab. */
@media (orientation:portrait) and (max-aspect-ratio:2/5) {
  .telescope-console,
  .telescope-console.cozy-panel {
    flex-grow: 0;
    margin-top: auto;
  }
  .control-bank { flex-grow: 0; }
}


/* The card screen is the night the card came out of, so the sheet reads as paper on top of it. */
.card-screen { overflow-y: auto; color: var(--text-invert); background: linear-gradient(135deg, var(--night-800), var(--scene) 58%, var(--night-600)); }
.spark { font-size: 24px; color: var(--accent); text-shadow: 0 2px 0 color-mix(in srgb, var(--shadow) 35%, transparent); }
.card-stage { flex: none; display: flex; flex-direction: column; gap: 14px; width: min(calc(100% - max(20px, env(safe-area-inset-left)) - max(20px, env(safe-area-inset-right))), 390px); margin: 0 auto; padding-block: 14px max(28px, env(safe-area-inset-bottom)); }
.card-panel { display: contents; }
/* The reveal is spoken over the sky: handwriting in paper ink, not card ink. */
.card-reveal { order: -1; min-height: 30px; margin: 0; color: var(--text-invert-dim); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.45; text-align: center; }
.card-reveal b { color: var(--accent); font-weight: 400; white-space: nowrap; }
.card-reveal small { display: block; margin-top: 3px; font-family: var(--font-ui); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.card-reveal b.is-typing ~ small { visibility: hidden; }
.card-reveal b.is-typing::after { content: ""; display: inline-block; width: .6em; height: 1em; margin-left: 2px; vertical-align: -2px; background: var(--accent); animation: caret-blink .5s steps(1) infinite; }
.card-frame { position: relative; width: min(100%, var(--card-full-width)); margin: 0 auto; }
.card-flash { position: absolute; inset: -8px; z-index: 2; pointer-events: none; opacity: 0; border-radius: var(--r-md); }
/* A merge makes something rarer, so the burst is gold into violet rather than gold into red. */
.card-flash.is-on { background: repeating-conic-gradient(var(--line) 0 25%, transparent 0 50%) 0 0 / 12px 12px; box-shadow: 0 0 0 4px var(--accent), 0 0 0 10px var(--special); animation: merge-flash .7s steps(7, end) both; }
@keyframes merge-flash { 0% { opacity: 1; background-color: var(--paper-edge); } 30% { opacity: .85; background-color: transparent; background-size: 8px 8px; } 100% { opacity: 0; background-size: 24px 24px; } }
@keyframes caret-blink { 50% { opacity: 0; } }
/* Every collectible uses one paper language; density changes through the three variants below. */
.card-view { --card-rim: var(--line-soft); position: relative; width: 100%; min-width: 0; aspect-ratio: var(--card-ratio); border: var(--line-w) solid var(--line); border-radius: var(--r-md); background: var(--paper-alt); color: var(--text); box-shadow: inset 0 0 0 var(--line-w-thin) var(--card-rim), var(--cel-paper), 0 var(--drop) 0 var(--shadow); overflow: hidden; }
.card-view::before { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--line) 7%, transparent) 0 2px, transparent 2px 9px); pointer-events: none; }
.card-view.is-contract { background: var(--paper); }
.card-view.is-contract::before { inset: 4px; background: repeating-linear-gradient(0deg, transparent 0 13px, color-mix(in srgb, var(--line) 10%, transparent) 13px 14px); }
.card-view.is-achievement::before { background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--line) 7%, transparent) 0 2px, transparent 2px 9px); }
.card-view--full { display: flex; flex-direction: column; width: min(100%, var(--card-full-width)); padding: 12px; box-shadow: inset 0 0 0 var(--line-w-thin) var(--card-rim), var(--cel-paper), 0 var(--drop) 0 var(--shadow), var(--haze); }
.card-view--full > * { position: relative; }
.card-view-heading { display: flex; align-items: start; justify-content: space-between; gap: 10px; padding: 4px 4px 8px; }
.card-view-heading > div { min-width: 0; }
.card-view-name { display: block; overflow: hidden; color: var(--text); text-overflow: ellipsis; }
.card-view--full .card-view-name { margin: 4px 0 0; font-size: var(--t-title); font-weight: 400; letter-spacing: .01em; line-height: 1.1; overflow-wrap: anywhere; }
.card-view-designation, .card-view-kicker { display: block; overflow: hidden; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: .06em; text-overflow: ellipsis; white-space: nowrap; }
.card-view-kicker { letter-spacing: var(--track-label); }
.card-view.is-achievement .card-view-kicker { color: var(--special-shade); }
.card-view.is-contract .card-view-kicker { color: var(--danger-deep); }
.card-view-designation { margin-top: 3px; }
.card-view-mark { flex: none; display: grid; place-items: center; min-width: 32px; min-height: 30px; margin-top: 2px; padding: 3px 8px 4px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-sm); background: var(--recess); color: var(--accent); font-size: var(--t-meta); font-variant-numeric: tabular-nums; letter-spacing: var(--track-label); rotate: 2deg; box-shadow: var(--sunken); }
.card-view.is-achievement .card-view-mark { background: var(--accent); color: var(--accent-text); rotate: -7deg; box-shadow: inset 0 3px 0 var(--accent-light), inset 0 -5px 0 var(--accent-shade), 0 3px 0 var(--shadow); }
.card-view.is-achievement.is-secret .card-view-mark { background: var(--special); box-shadow: inset 0 3px 0 var(--special-light), inset 0 -5px 0 var(--special-shade), 0 3px 0 var(--shadow); }
.card-view.is-contract .card-view-mark { width: 40px; height: 40px; padding: 0; border-radius: 50%; background: var(--danger); color: var(--text); font-size: var(--t-title); rotate: 0deg; box-shadow: inset 3px 4px 0 var(--danger-light), inset 0 -4px 0 var(--danger-shade), 0 3px 0 var(--shadow); }
.card-view-art { position: relative; display: grid; place-items: center; overflow: hidden; border: var(--line-w) solid var(--line); border-radius: var(--r-sm); background: radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--glass), var(--night-500) 45%), var(--glass) 78%); box-shadow: var(--sunken); }
.card-view.is-achievement .card-view-art { background: repeating-radial-gradient(circle, color-mix(in srgb, var(--glass), var(--night-500) 35%) 0 12px, var(--glass) 12px 24px); }
.card-view-art canvas { position: absolute; top: 50%; left: 50%; width: auto; height: 90%; max-width: 90%; aspect-ratio: 1; translate: -50% -50%; image-rendering: auto; }
.card-view--full .card-view-art { flex: 1 1 auto; min-height: 0; }
.card-view-stars { position: absolute; top: 10px; right: 12px; color: var(--accent); opacity: .7; }
.card-view:not(.is-celestial) .card-view-stars { display: none; }
.card-view-emblem { display: grid; place-items: center; color: var(--accent); line-height: 1; text-shadow: 0 4px 0 var(--shadow); }
.card-view--full .card-view-emblem { width: 124px; height: 124px; border: 7px double var(--accent); border-radius: 50%; background: var(--recess-deep); font-size: 84px; box-shadow: 0 0 0 6px var(--glass), 0 8px 0 6px var(--shadow); }
.card-view.is-secret .card-view-emblem { border-color: var(--special-light); color: var(--special-light); }
.card-view.is-contract .card-view-emblem.is-empty { color: var(--danger); }
.card-view-title { display: flex; align-items: baseline; gap: 9px; margin: 8px 0 0; padding: 6px 10px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-sm); background: var(--paper-edge); box-shadow: var(--sunken); }
.card-view-title span { flex: none; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.card-view-title b { overflow: hidden; color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); font-weight: 400; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
.card-view-facts { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); margin: 9px 0 0; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-sm); background: var(--paper); box-shadow: var(--sunken); overflow: hidden; }
.card-view-facts div { min-width: 0; padding: 8px 6px; text-align: center; }
.card-view-facts div + div { border-left: var(--line-w-hair) solid var(--line-soft); }
.card-view-facts dt { color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.card-view-facts dd { margin: 4px 0 0; color: var(--text); font-family: var(--font-ui); font-size: var(--t-label); font-weight: 400; font-variant-numeric: tabular-nums; line-height: 1.25; }
.card-view.is-contract .card-view-facts { background: var(--paper-edge); }
.card-view.is-contract .card-view-facts dt { color: var(--danger-deep); }
.card-view.is-contract .card-view-facts dd { font-family: var(--font-hand); }
.card-view-note { min-height: 31px; margin: 10px 5px 5px; color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.4; }
.card-view--full footer { display: flex; justify-content: space-between; gap: 8px; padding: 7px 5px 1px; border-top: var(--line-w-hair) solid var(--line-soft); color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.card-view--full footer b { font-weight: 400; }
/* The copies rack is teal panelling: structure the paper chips sit in. */
.card-copies { padding: 11px; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--surface-raised); color: var(--text); box-shadow: var(--cel), var(--haze); }
.card-copies header { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 10px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.card-copies header b { color: var(--text); font-weight: 400; }
.copy-strip { display: flex; flex-wrap: wrap; gap: 8px; }
.copy-chip { display: block; width: var(--card-thumbnail-width); padding: 0; border-radius: var(--r-md); background: transparent; color: var(--text); text-align: left; }
/* The copy on show wears a gold rim; the merge button stays the one thing to press. */
.copy-chip.is-current .card-view { --card-rim: var(--accent); background: var(--paper-edge); }
.copy-chip:active .card-view { translate: 0 2px; box-shadow: inset 0 0 0 var(--line-w-thin) var(--card-rim), var(--cel-paper), 0 1px 0 var(--shadow); }
.merge-button { width: 100%; min-height: 46px; margin-top: 12px; padding: 8px 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--accent); color: var(--accent-text); font-family: var(--font-ui); font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; box-shadow: var(--cel-accent), 0 var(--drop) 0 var(--shadow); transition: translate .12s, box-shadow .12s; }
.merge-button:active { translate: 0 var(--press); box-shadow: var(--cel-accent), 0 1px 0 var(--shadow); }
.card-actions { display: grid; gap: 12px; }
.card-actions .primary-button { min-height: 52px; }
.card-album-action { display: grid; gap: 7px; }
.card-album-action .secondary-button { width: 100%; }
.card-provenance { display: flex; align-items: baseline; justify-content: center; gap: 6px; padding-inline: 8px; color: var(--text-invert-dim); font-size: var(--t-meta); line-height: 1.35; text-align: center; }
.card-provenance[hidden] { display: none; }
.card-provenance i { flex: none; color: var(--accent); font-style: normal; }
/* The album is the room the collection hangs in, not another sky: a teal wall lit from above. */
.album-screen { --album-gutter-left: max(20px, env(safe-area-inset-left)); --album-gutter-right: max(20px, env(safe-area-inset-right)); --album-card-width: min(var(--card-compact-width), calc((100vw - var(--album-gutter-left) - var(--album-gutter-right) - 14px) / 2)); background: linear-gradient(var(--surface-edge), var(--surface) 52%, var(--well)); overflow-y: auto; }
.album-total { color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.album-summary { display: flex; align-items: center; justify-content: center; gap: 28px; margin: 20px var(--album-gutter-right) 12px var(--album-gutter-left); padding: 13px; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--paper); color: var(--text); box-shadow: var(--cel-paper), var(--haze); }
.album-summary div { text-align: center; }
.album-summary span, .album-summary small { display: block; }
.album-summary span { color: var(--text); font-size: var(--t-title); font-variant-numeric: tabular-nums; }
.album-summary small { color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.album-summary i { width: var(--line-w-thin); height: 30px; border-radius: var(--r-pill); background: var(--line-soft); }
.album-grid { display: grid; grid-template-columns: repeat(auto-fill, var(--album-card-width)); justify-content: center; gap: 14px; padding: 8px var(--album-gutter-right) 28px var(--album-gutter-left); }
/* Compact cards are browsed; the button owns interaction while the card owns appearance. */
.card-button { display: block; min-width: 0; padding: 0; border-radius: var(--r-md); background: transparent; color: var(--text); text-align: left; }
.card-button--compact { width: var(--album-card-width, var(--card-compact-width)); justify-self: center; }
.card-button .card-view { height: 100%; }
.card-button:active .card-view { translate: 0 var(--press); box-shadow: inset 0 0 0 var(--line-w-thin) var(--card-rim), var(--cel-paper), 0 2px 0 var(--shadow); }
.card-button:focus-visible, .copy-chip:focus-visible, .workshop-pick:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.card-view--compact { display: flex; flex-direction: column; padding: 6px; }
.card-view--compact .card-view-art { width: 100%; aspect-ratio: 1; border-width: var(--line-w-thin); }
.card-view--compact .card-view-emblem { font-size: 52px; text-shadow: 0 3px 0 var(--shadow); }
.card-view--compact .card-view-name { margin: 8px 2px 6px; font-size: var(--t-body); font-weight: 400; line-height: 1.2; overflow-wrap: anywhere; }
.card-view-icons { display: flex; align-items: center; gap: 4px; }
.card-view--compact .card-view-icons { flex-wrap: wrap; min-height: 23px; margin: auto 2px 0; padding-top: 5px; border-top: var(--line-w-hair) solid var(--line-soft); }
.card-view-icon { display: inline-grid; place-items: center; min-width: 20px; min-height: 20px; padding: 1px 5px; border: var(--line-w-hair) solid var(--line); border-radius: var(--r-pill); background: var(--recess); color: var(--text-dim); font-size: var(--t-meta); font-style: normal; font-variant-numeric: tabular-nums; line-height: 1; box-shadow: var(--sunken); }
.card-view-icon.is-star, .card-view-icon.is-achievement, .card-view-icon.is-secret { color: var(--special-shade); }
.card-view-icon.is-contract, .card-view-icon.is-last { background: var(--danger); color: var(--text); }
.card-view-icon.is-mergeable { background: var(--success); color: var(--text); }
.card-view-icon.is-deep { background: var(--special); color: var(--paper-edge); }
.empty-album { display: none; margin: auto; padding: 40px max(40px, env(safe-area-inset-right)) 40px max(40px, env(safe-area-inset-left)); text-align: center; }
.empty-album span, .empty-album strong { display: block; }
.empty-album > span { color: var(--accent); font-size: 32px; text-shadow: 0 3px 0 var(--shadow); }
.empty-album strong { margin: 12px; color: var(--text); font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; }
.empty-album p { color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.45; }
.empty-album button { margin: 22px auto; }
.album-screen.is-empty .empty-album { display: block; }
.album-screen.is-empty .album-summary, .album-screen.is-empty .album-grid { display: none; }

@media (min-width:960px){
  .topbar{padding-left:max(28px,env(safe-area-inset-left));padding-right:max(28px,env(safe-area-inset-right))}
  .home-screen:is(.is-active,.is-transitioning){display:grid;grid-template-columns:minmax(360px,1fr) minmax(390px,520px);grid-template-rows:1fr;column-gap:clamp(48px,8vw,140px);padding:clamp(24px,min(7vw,12svh),108px)}
  .home-screen::before{display:none}
  /* The painting spans the whole frame here; only the moon and the menu move. */
  .home-sky::after{width:clamp(92px,10vw,150px);height:clamp(92px,10vw,150px);right:10%;top:14%}
  .brand{grid-column:1;grid-row:1;align-self:center;margin:0;position:relative}
  .brand h1{font-size:clamp(72px,8vw,124px)}
  .brand p{font-size:var(--t-label)}
  .home-actions{grid-column:2;grid-row:1;align-self:center;margin:0}
  .album-screen{--album-gutter-left:max(32px,env(safe-area-inset-left));--album-gutter-right:max(32px,env(safe-area-inset-right))}
  .album-grid{gap:22px;padding-top:14px;padding-bottom:36px}
  .album-summary{width:min(720px,calc(100% - var(--album-gutter-left) - var(--album-gutter-right)));margin:24px auto 18px}
  .card-stage{flex:1 0 auto;display:grid;grid-template-columns:minmax(340px,380px) minmax(320px,400px);align-items:center;justify-content:center;gap:clamp(40px,6vw,88px);width:auto;margin:0;padding:36px max(32px,env(safe-area-inset-right)) 36px max(32px,env(safe-area-inset-left))}
  .card-frame{width:100%}
  .card-panel{display:flex;flex-direction:column;gap:16px}
  .card-reveal{order:0;min-height:0;font-size:var(--t-body);text-align:left}
}
@media (pointer:fine), (pointer:coarse) and (min-width:600px) and (min-height:600px){
  .logout-button{position:static;display:block;margin-top:clamp(8px,1.8svh,14px)}
}
@media (orientation:portrait){
  .logout-button{position:static;display:block;margin-top:clamp(8px,1.8svh,14px)}
}
/* Phones in landscape use the desktop composition, compressed vertically so the whole menu stays
   above the fold. The height guard leaves tablets and ordinary desktop windows to the layout above. */
@media (orientation:landscape) and (max-width:959px) and (max-height:600px){
  .home-screen:is(.is-active,.is-transitioning){display:grid;grid-template-columns:minmax(0,4fr) minmax(280px,5fr);grid-template-rows:1fr;column-gap:clamp(16px,5vw,42px);overflow:hidden;padding:max(12px,env(safe-area-inset-top)) max(18px,env(safe-area-inset-right)) max(12px,env(safe-area-inset-bottom)) max(18px,env(safe-area-inset-left))}
  .home-screen::before{display:none}
  .brand,.brand:has(.contract-hint:not([hidden])),.brand:has(.goal-hint:not([hidden])){grid-column:1;grid-row:1;align-self:center;min-width:0;margin:0}
  .brand h1{font-size:clamp(38px,12svh,54px)}
  .brand p{margin:clamp(5px,1.5svh,8px) 0;font-size:clamp(10px,1.8vw,13px)}
  .logout-button{position:static;display:block;margin-top:clamp(5px,1.5svh,9px);padding:6px 11px 8px}
  .home-actions{grid-column:2;grid-row:1;align-self:center;justify-self:end;width:min(100%,420px);gap:clamp(7px,2svh,10px);margin:0}
  .home-actions .primary-button{min-height:clamp(50px,15svh,60px);padding-block:6px}
  .home-actions .secondary-button{min-height:clamp(42px,12svh,50px);padding-block:6px}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important}.screen.is-transitioning,.home-sky i{animation:none!important}.card-flash{display:none}.card-reveal b.is-typing::after{animation:none}}


.album-goals { padding: 4px var(--album-gutter-right) max(30px, env(safe-area-inset-bottom)) var(--album-gutter-left); }
.album-goals > header { display: flex; align-items: end; justify-content: space-between; gap: 12px; margin-bottom: 14px; padding-top: 18px; border-top: var(--line-w-thin) dashed var(--line-soft); }
.album-goals > header strong { display: block; margin-top: 4px; color: var(--text); font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; }
.album-goals > header b { color: var(--text); font-size: var(--t-meta); font-weight: 400; letter-spacing: var(--track-label); }
.goal-grid { display: grid; grid-template-columns: repeat(auto-fill, var(--album-card-width)); justify-content: center; gap: 14px; }
.goal-slot { display: flex; flex-direction: column; min-width: 0; padding: 7px; border-radius: var(--r-md); text-align: left; }
/* A goal is a note about the game, not a piece of it: dashed ink, no drop, nothing to pick up. */
.goal-slot { border: var(--line-w-thin) dashed var(--line); background: color-mix(in srgb, var(--surface-raised) 80%, transparent); color: var(--text); box-shadow: none; }
.goal-art { display: grid; place-items: center; aspect-ratio: 5 / 3; overflow: hidden; }
.goal-art { border: var(--line-w-thin) dashed var(--line-soft); border-radius: var(--r-sm); background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--line) 9%, transparent) 0 4px, transparent 4px 10px); }
.goal-emblem { color: color-mix(in srgb, var(--line) 38%, transparent); font-size: 50px; line-height: 1; }
/* Once a goal is under way its emblem takes the objective colour. */
.goal-slot.is-started .goal-emblem { color: var(--special-shade); }
.goal-name { margin: 8px 2px 4px; color: var(--text); font-size: var(--t-body); font-weight: 400; letter-spacing: .01em; }
.goal-text { flex: 1; margin: 0 2px; color: var(--text); font-family: var(--font-hand); font-size: var(--t-label); line-height: 1.45; }
.goal-meter { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 7px; margin: 8px 2px 0; padding-top: 6px; border-top: var(--line-w-hair) dashed var(--line-soft); }
.goal-bar { height: 10px; padding: 0; overflow: hidden; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: var(--recess-deep); box-shadow: var(--sunken); }
.goal-bar b { display: block; width: 0; height: 100%; background: var(--success); box-shadow: inset 0 2px 0 var(--success-light); }
.goal-count { color: var(--text); font-size: var(--t-label); font-style: normal; font-weight: 400; font-variant-numeric: tabular-nums; }
.achievement-screen { overflow-y: auto; color: var(--text-invert); background: linear-gradient(135deg, var(--night-800), var(--scene) 58%, var(--night-600)); }
.achievement-stage { flex: none; display: flex; flex-direction: column; gap: 18px; width: min(calc(100% - 40px), var(--card-full-width)); margin: 0 auto; padding-block: 22px max(28px, env(safe-area-inset-bottom)); }
.achievement-caption { margin: 0; color: var(--text-invert-dim); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.5; text-align: center; }

.achievement-notice { position: absolute; z-index: 30; left: 50%; top: max(12px, env(safe-area-inset-top)); width: min(calc(100% - 32px), 380px); translate: -50% 0; }
.achievement-notice[hidden] { display: none; }
/* A notice floats over the night, so it is a paper pill with ink on it, hazed onto the scene. */
.achievement-notice button { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px; width: 100%; padding: 9px 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--text); box-shadow: var(--notice-cel), 0 var(--drop) 0 var(--shadow), var(--haze); text-align: left; }
.achievement-notice button:active { translate: 0 var(--press); box-shadow: var(--notice-cel), 0 1px 0 var(--shadow), var(--haze); }
.achievement-notice-emblem { display: grid; place-items: center; width: 40px; height: 40px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--recess); color: var(--accent); font-size: 26px; line-height: 1; box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 4px var(--recess), inset 0 0 0 5px var(--accent), 0 2px 0 var(--shadow); }
.achievement-notice small, .achievement-notice b { display: block; }
.achievement-notice small { color: var(--special-shade); font-size: var(--t-meta); font-weight: 400; letter-spacing: var(--track-label); }
.achievement-notice b { display: -webkit-box; margin-top: 4px; overflow: hidden; color: var(--text); font-size: var(--t-body); font-weight: 400; line-height: 1.25; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.achievement-notice em { color: var(--text-dim); font-size: 26px; font-style: normal; line-height: 1; }
.achievement-notice.is-on { animation: achievement-notice-in .36s steps(5, end) both; }
@keyframes achievement-notice-in { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: none; } }

@media (min-width:960px){
  .album-goals{width:min(1026px,calc(100% - 64px));margin:0 auto;padding:4px 0 36px}
  .goal-grid{gap:22px}
  .achievement-stage{padding-block:40px}
}
@media (prefers-reduced-motion:reduce){.achievement-notice.is-on{animation:none}}

/* Alien Groceries keeps Little Planets' instrument language, but the telescope is now the
   tractor deck of a stationary UFO. These rules deliberately sit after the inherited kit. */
.grocery-screen { display: flex; background: linear-gradient(var(--night-800), var(--night-700) 58%, var(--night-600)); }
.telescope-screen .grocery-topbar { grid-template-columns: minmax(0, 1fr); }
.grocery-topbar .topbar-title { grid-column: 1; }
.orbit-bearing { font-variant-numeric: tabular-nums; }
.grocery-workbench { position: relative; display: block; }
.grocery-workbench .telescope-frame { position: absolute; inset: 0; display: grid; min-height: 0; padding: 0; }
#planet-canvas { display: block; width: 100%; height: 100%; border-radius: 0; image-rendering: pixelated; }
.grocery-workbench .grocery-stage { --scope-size: auto; width: 100%; height: 100%; aspect-ratio: auto; overflow: hidden; border: 0; border-radius: 0; background: var(--glass); box-shadow: none; }
.grocery-stage::before { z-index: 4; border-radius: 0; }
.grocery-stage::after { content: none; }
/* The centre remains a small tractor-beam aiming pip, not a telescope frame. */
.grocery-reticle { z-index: 3; left: var(--aim-x, 50%); top: var(--aim-y, 50%); width: 38px; height: 38px; border: 0; border-radius: 0; outline: 0; box-shadow: none; background: linear-gradient(90deg, transparent 17px, color-mix(in srgb, var(--sky) 80%, transparent) 17px 21px, transparent 21px), linear-gradient(transparent 17px, color-mix(in srgb, var(--sky) 80%, transparent) 17px 21px, transparent 21px); clip-path: polygon(0 0, 13px 0, 13px 4px, 4px 4px, 4px 13px, 0 13px, 0 0, 100% 0, 100% 13px, calc(100% - 4px) 13px, calc(100% - 4px) 4px, calc(100% - 13px) 4px, calc(100% - 13px) 0, 100% 0, 100% 100%, calc(100% - 13px) 100%, calc(100% - 13px) calc(100% - 4px), calc(100% - 4px) calc(100% - 4px), calc(100% - 4px) calc(100% - 13px), 100% calc(100% - 13px), 100% 100%, 0 100%, 0 calc(100% - 13px), 4px calc(100% - 13px), 4px calc(100% - 4px), 13px calc(100% - 4px), 13px 100%, 0 100%); }
.grocery-reticle::before, .grocery-reticle::after { content: none; }
.grocery-stage.has-lock .grocery-reticle { background: linear-gradient(90deg, transparent 17px, var(--success) 17px 21px, transparent 21px), linear-gradient(transparent 17px, var(--success) 17px 21px, transparent 21px); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--success) 65%, transparent)); }
.grocery-order { position: absolute; z-index: 3; left: var(--aim-x, 50%); top: 8%; width: min(72%, 250px); translate: -50%; padding: 7px 13px 8px; border: var(--line-w-thin) solid color-mix(in srgb, var(--sky) 70%, transparent); border-radius: var(--r-md); background: color-mix(in srgb, var(--glass) 78%, transparent); color: var(--text-invert); text-align: center; box-shadow: 0 4px 0 color-mix(in srgb, var(--shadow) 45%, transparent); }
.grocery-order span, .grocery-order strong, .grocery-order small { display: block; }
.grocery-order span { color: var(--sky); font-size: var(--t-micro); letter-spacing: var(--track-label); }
.grocery-order strong { margin-top: 2px; font-family: var(--font-display); font-size: var(--t-title); font-weight: 600; line-height: 1; }
.grocery-order small { margin-top: 2px; color: var(--accent-light); font-family: var(--font-hand); font-size: var(--t-label); }
.grocery-readout { left: var(--aim-x, 50%); bottom: 8%; }
.grocery-console { position: absolute; z-index: 5; right: max(16px, env(safe-area-inset-right)); bottom: max(16px, env(safe-area-inset-bottom)); left: max(16px, env(safe-area-inset-left)); display: flex; flex: none; gap: 10px; max-height: calc(100% - 32px); overflow: hidden; padding: 14px; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); box-shadow: var(--cel), 0 8px 24px color-mix(in srgb, var(--shadow) 58%, transparent); }
.grocery-console .signal-readout { flex: none; margin-bottom: 2px; }
.grocery-control-bank { flex: none; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; grid-template-areas: "orbit orbit" "longitude latitude"; gap: 10px 12px; }
.grocery-control-bank [data-control-group="orbit-altitude"] { grid-area: orbit; }
.grocery-control-bank [data-control-group="longitude"] { grid-area: longitude; }
.grocery-control-bank [data-control-group="latitude"] { grid-area: latitude; }
.grocery-control-bank[data-focus="orbit-altitude"] { grid-template-areas: "orbit orbit" "longitude latitude"; }
.grocery-control-bank[data-focus="longitude"] { grid-template-areas: "orbit latitude" "longitude longitude"; }
.grocery-control-bank[data-focus="latitude"] { grid-template-areas: "orbit longitude" "latitude latitude"; }
.grocery-control-bank:is([data-focus="longitude"], [data-focus="latitude"]) { --dial-size: 72px; }
.grocery-control-bank[data-focus="longitude"] [data-control-group="longitude"],
.grocery-control-bank[data-focus="latitude"] [data-control-group="latitude"] { --dial-size: 210px; }
.altitude-assembly { grid-template: "label label" auto "track track" auto "ticks ticks" auto / 2fr 1fr; }
.tractor-button { display: grid; grid-template-columns: 38px minmax(0, 1fr); grid-template-rows: auto auto; align-items: center; flex: none; width: 100%; min-height: 54px; padding: 7px 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-md); background: var(--accent); color: var(--accent-text); box-shadow: var(--cel-accent), 0 4px 0 var(--shadow); text-align: left; }
.tractor-button span { grid-row: 1 / 3; display: grid; place-items: center; width: 30px; height: 30px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--recess); color: var(--accent-light); font-size: 25px; line-height: 1; }
.tractor-button b { font-size: var(--t-label); font-weight: 400; letter-spacing: .08em; }
.tractor-button small { overflow: hidden; font-family: var(--font-hand); font-size: var(--t-meta); text-overflow: ellipsis; white-space: nowrap; }
.tractor-button:not(:disabled):active { translate: 0 3px; box-shadow: var(--cel-accent), 0 1px 0 var(--shadow); }
.tractor-button:disabled { background: var(--metal); color: var(--text-dim); box-shadow: var(--cel-metal), 0 3px 0 var(--shadow); cursor: not-allowed; }
.tractor-button:disabled span { color: var(--metal); }
.cargo-count { display: flex; justify-content: space-between; flex: none; margin: 0; padding-top: 5px; border-top: var(--line-w-hair) dashed var(--line-soft); color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.cargo-count b { font-weight: 400; }
.capture-toast { position: fixed; z-index: 20; left: 50%; top: max(16px, env(safe-area-inset-top)); width: min(380px, calc(100% - 32px)); translate: -50%; padding: 11px 15px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--text); box-shadow: var(--cel-paper), 0 var(--drop) 0 var(--shadow), var(--haze); font-family: var(--font-hand); font-size: var(--t-body); text-align: center; animation: grocery-toast-in .3s steps(4, end) both; }
.capture-toast[hidden] { display: none; }
@keyframes grocery-toast-in { from { opacity: 0; transform: translateY(-12px); } }

@media (orientation: landscape) {
  .grocery-console { top: 50%; right: max(16px, env(safe-area-inset-right)); bottom: auto; left: auto; width: min(410px, calc(42% - 24px)); translate: 0 -50%; border: var(--line-w) solid var(--line); box-shadow: var(--cel), 0 8px 24px color-mix(in srgb, var(--shadow) 58%, transparent); }
  .grocery-control-bank { --dial-size: 106px; }
  .grocery-console { padding-block: 14px; }
  .grocery-order { top: 7%; }
}
@media (orientation: landscape) and (max-height: 590px) {
  .grocery-console .signal-readout { display: none; }
  .grocery-control-bank { --dial-size: 88px; grid-template-rows: auto minmax(82px, 1fr); }
  .tractor-button { min-height: 47px; }
  .cargo-count { display: none; }
}
@media (orientation: portrait) and (max-height: 760px) {
  .grocery-control-bank { --dial-size: 124px; grid-template-rows: auto minmax(90px, 1fr); }
  .grocery-order { top: 6%; }
  .grocery-readout { bottom: 6%; }
}
@media (orientation: portrait) {
  .grocery-readout { top: calc(var(--aim-y, 50%) + min(26cqw, 110px)); bottom: auto; }
}


.workshop-screen { overflow-y: auto; background: linear-gradient(170deg, var(--night-800), var(--scene) 52%, var(--night-600)); }
.workshop-total { color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.secondary-button .workshop-badge.is-ready { background: var(--success); color: var(--text); }
.workshop-stage { flex: none; display: flex; flex-direction: column; gap: 16px; width: min(calc(100% - 40px), 420px); margin: 0 auto; padding-block: 16px max(28px, env(safe-area-inset-bottom)); }
.workshop-rig { display: flex; flex-direction: column; gap: 10px; }
/* The bench is a box you look into: a pegboard wall cut into the screen, a timber slab along the
   bottom, and the telescope standing on it. */
.workshop-bench { position: relative; height: 176px; overflow: hidden; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: radial-gradient(circle, color-mix(in srgb, var(--line) 22%, transparent) 0 1.5px, transparent 2px) 0 0 / 14px 14px, var(--well); box-shadow: var(--sunken), 0 var(--drop) 0 var(--shadow); }
.workshop-bench::before { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; border-radius: inherit; box-shadow: inset 0 0 0 var(--line-w-thin) var(--line-soft); }
.workshop-bench::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 28px; border-top: var(--line-w) solid var(--line); background: repeating-linear-gradient(92deg, color-mix(in srgb, var(--timber-shade) 22%, transparent) 0 2px, transparent 2px 26px), var(--timber); box-shadow: var(--cel-timber); }
.workshop-bench-label { position: absolute; top: 10px; left: 16px; z-index: 2; color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.bench-scope { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; height: 176px; transform-origin: 50% 148px; }
.bench-scope i { position: absolute; display: block; }
.bench-leg { left: calc(50% - 3px); top: 88px; width: 6px; height: 68px; border-radius: var(--r-xs); background: var(--metal); box-shadow: inset 2px 0 0 var(--metal-light), inset -2px 0 0 var(--metal-shade), 0 0 0 var(--line-w-thin) var(--line); transform-origin: 50% 0; }
.bench-leg:nth-child(1) { rotate: 30deg; }
.bench-leg:nth-child(2) { rotate: -30deg; }
.bench-leg:nth-child(3) { height: 60px; background: var(--metal-shade); box-shadow: inset -2px 0 0 var(--metal), 0 0 0 var(--line-w-thin) var(--line); }
.bench-tube { left: 50%; top: 50px; width: min(64%, 280px); height: 26px; translate: -50% 0; rotate: -14deg; border: var(--line-w) solid var(--line); border-radius: var(--r-sm); background: linear-gradient(90deg, var(--paper) 0 12%, var(--accent) 12% 17%, var(--paper) 17% 78%, var(--accent) 78% 83%, var(--paper) 83%); box-shadow: inset 0 4px 0 color-mix(in srgb, var(--paper-edge) 70%, transparent), inset 0 -5px 0 color-mix(in srgb, var(--shadow) 22%, transparent), 0 4px 0 var(--shadow); }
/* Not fitted yet: a dashed socket with a ghost of a part in it. */
.bench-part { border: var(--line-w) dashed var(--line-soft); border-radius: var(--r-xs); background: color-mix(in srgb, var(--recess) 28%, transparent); cursor: pointer; }
.bench-mount { left: 50%; top: 72px; width: 44px; height: 24px; translate: -50% 0; }
.bench-lens { right: -17px; top: 50%; width: 22px; height: 42px; translate: 0 -50%; }
.bench-eyepiece { left: 10%; top: -17px; width: 16px; height: 18px; }
.bench-part.is-ready { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 30%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 26%, transparent); animation: bench-ready 1.2s steps(1) infinite; }
.bench-part.is-selected { outline: var(--line-w-thin) solid var(--sky); outline-offset: 3px; }
.bench-part.is-installed { border-style: solid; border-color: var(--line); box-shadow: 0 3px 0 var(--shadow); }
.bench-lens.is-installed { border-radius: var(--r-sm); background: linear-gradient(135deg, var(--glass) 0 18%, var(--sky) 18% 58%, var(--special) 58%); box-shadow: inset 0 var(--band-light) 0 color-mix(in srgb, #fff 32%, transparent), inset 0 -4px 0 color-mix(in srgb, var(--shadow) 30%, transparent), 0 0 0 var(--line-w-thin) var(--metal-light), 0 0 0 4px var(--line); }
.bench-mount.is-installed { background: var(--metal); box-shadow: var(--cel-metal), 0 3px 0 var(--shadow); }
.bench-mount.is-installed::after { content: ""; position: absolute; right: -15px; top: 1px; width: 12px; height: 14px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); background: var(--surface-raised); box-shadow: inset 3px 3px 0 var(--success); animation: bench-led 1s steps(1) infinite; }
.bench-eyepiece.is-installed { left: 6%; top: -19px; width: 28px; height: 20px; border-radius: var(--r-xs); background: linear-gradient(90deg, var(--danger) 0 20%, var(--accent) 20% 40%, var(--success) 40% 60%, var(--sky) 60% 80%, var(--special) 80%); box-shadow: inset 0 var(--band-light) 0 color-mix(in srgb, #fff 38%, transparent), inset 0 -3px 0 color-mix(in srgb, var(--shadow) 26%, transparent), 0 3px 0 var(--shadow); }
.bench-part.is-new { animation: bench-pop .6s steps(6) both; }
.bench-scope[data-reach="2"] .bench-tube { top: 47px; height: 32px; }
.bench-scope:is([data-reach="3"], [data-reach="4"]) .bench-tube { top: 44px; height: 38px; background: linear-gradient(90deg, var(--paper) 0 8%, var(--accent) 8% 12%, var(--paper) 12% 40%, var(--accent) 40% 43%, var(--paper) 43% 76%, var(--accent) 76% 80%, var(--paper) 80%); }
.bench-scope[data-reach="2"] .bench-lens.is-installed { right: -20px; width: 26px; height: 52px; }
.bench-scope:is([data-reach="3"], [data-reach="4"]) .bench-lens.is-installed { right: -23px; width: 30px; height: 62px; background: linear-gradient(135deg, var(--glass) 0 14%, var(--special) 14% 42%, var(--sky) 42% 70%, var(--special) 70%); }
.bench-scope[data-reach="4"]::before, .bench-scope[data-reach="4"]::after { content: ""; position: absolute; left: calc(50% + 50px); width: 68px; }
.bench-scope[data-reach="4"]::before { top: 128px; height: 12px; background: repeating-linear-gradient(90deg, var(--sky) 0 6px, var(--special) 6px 10px, transparent 10px 18px) 2px 2px / 100% 8px no-repeat, repeating-linear-gradient(90deg, var(--line) 0 14px, transparent 14px 18px); }
.bench-scope[data-reach="4"]::after { top: 140px; height: 8px; background: repeating-linear-gradient(90deg, transparent 0 5px, var(--metal) 5px 9px, transparent 9px 18px); }
.bench-scope:is([data-control="2"], [data-control="3"]) .bench-mount::before { content: ""; position: absolute; left: -17px; top: 11px; width: 12px; height: 12px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: repeating-conic-gradient(var(--metal-light) 0 45deg, var(--metal-shade) 45deg 90deg); }
.bench-scope[data-control="3"] .bench-tube::before { content: ""; position: absolute; left: 40%; top: -17px; width: 36px; height: 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-xs); background: linear-gradient(90deg, var(--surface-raised) 0 72%, var(--success) 72%); box-shadow: inset 0 2px 0 var(--raised-light); }
.bench-scope:is([data-analysis="2"], [data-analysis="3"]) .bench-eyepiece::before { content: ""; position: absolute; left: -14px; top: 1px; width: 11px; height: 11px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: conic-gradient(var(--danger) 0 25%, var(--success) 0 50%, var(--sky) 0 75%, var(--accent) 0); }
.bench-scope[data-analysis="3"] .bench-eyepiece::after { content: ""; position: absolute; left: 3px; top: -17px; width: 22px; height: 14px; border: var(--line-w) solid var(--line); border-radius: var(--r-xs); background: repeating-linear-gradient(90deg, var(--special) 0 2px, var(--special-light) 2px 4px); }
@keyframes bench-ready { 50% { border-color: var(--line-soft); } }
@keyframes bench-led { 50% { box-shadow: inset 3px 3px 0 var(--well); } }
@keyframes bench-pop { 0% { scale: 1.9; filter: brightness(2.2); } 60% { scale: .9; } 100% { scale: 1; filter: none; } }
.workshop-flash { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; }
.workshop-flash.is-on { background: repeating-conic-gradient(var(--paper-edge) 0 25%, transparent 0 50%) 0 0 / 12px 12px; box-shadow: inset 0 0 0 4px var(--accent), inset 0 0 0 10px var(--danger); animation: merge-flash .7s steps(7, end) both; }
.workshop-slots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.workshop-slot { --slot-face: var(--cel-surface); display: flex; flex-direction: column; justify-content: center; gap: 5px; min-width: 0; min-height: 50px; padding: 7px 9px; border: var(--line-w) solid var(--line); border-radius: var(--r-md); background: var(--surface); color: var(--text); box-shadow: var(--slot-face), 0 4px 0 var(--shadow); text-align: left; }
.workshop-slot-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; min-width: 0; }
.workshop-slot small, .workshop-slot b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.workshop-slot small { min-width: 0; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.workshop-slot b { padding-bottom: 2px; color: var(--text); font-size: var(--t-label); font-weight: 400; letter-spacing: .05em; }
.workshop-slot:active { translate: 0 2px; box-shadow: var(--slot-face), 0 2px 0 var(--shadow); }
.workshop-slot.is-selected { --slot-face: inset 0 0 0 var(--line-w-thin) var(--accent), var(--cel-raised); background: var(--surface-raised); }
/* Gold and lime are both lighter than the teal they sit on, so the state is a highlighter stripe
   under an ink word rather than coloured text. */
.workshop-slot.is-selected small { color: var(--text); }
.workshop-slot.is-ready b { box-shadow: inset 0 -4px 0 var(--accent); }
.workshop-slot.is-complete b { box-shadow: inset 0 -4px 0 var(--success); }
.workshop-pips { flex: none; display: flex; gap: 2px; }
.workshop-pips i { width: 6px; height: 9px; border-radius: var(--r-xs); background: var(--well); box-shadow: inset 0 2px 0 color-mix(in srgb, var(--shadow) 35%, transparent), 0 0 0 var(--line-w-hair) var(--line); }
.workshop-pips i.is-owned { background: var(--success); box-shadow: inset 0 2px 0 var(--success-light), 0 0 0 var(--line-w-hair) var(--line); }
.workshop-pips i.is-next { background: var(--recess-deep); box-shadow: 0 0 0 var(--line-w-hair) var(--line); }
.workshop-pips i.is-ready { background: var(--accent); box-shadow: inset 0 2px 0 var(--accent-light), 0 0 0 var(--line-w-hair) var(--line); animation: workshop-blink 1s steps(1) infinite; }
@keyframes workshop-blink { 50% { background: var(--well); box-shadow: 0 0 0 var(--line-w-hair) var(--line); } }
/* A technical sheet lying on the bench: cut-by-hand corners, ruled lines, a stamp when it is done. */
.workshop-sheet { position: relative; padding: 15px 15px 17px; border: var(--line-w) solid var(--line); border-radius: var(--r-hand); background: var(--paper); color: var(--text); box-shadow: var(--cel-paper), 0 var(--drop) 0 var(--shadow), var(--haze); }
.workshop-sheet::before { content: ""; position: absolute; inset: 4px; border-radius: var(--r-md); background: repeating-linear-gradient(0deg, transparent 0 17px, color-mix(in srgb, var(--line) 12%, transparent) 17px 18px); pointer-events: none; }
.workshop-sheet > * { position: relative; }
.workshop-sheet header { display: flex; align-items: start; justify-content: space-between; gap: 10px; min-height: 22px; }
.workshop-ladder { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; min-width: 0; }
.workshop-ladder > small { margin-left: 3px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.workshop-tag { padding: 3px 10px 4px; border: var(--line-w-hair) solid var(--line); border-radius: var(--r-pill); background: var(--surface-raised); color: var(--text); font-size: var(--t-meta); letter-spacing: var(--track-label); box-shadow: 0 2px 0 color-mix(in srgb, var(--shadow) 35%, transparent); }
.workshop-rungs { display: flex; gap: 4px; }
.workshop-rung { position: relative; display: grid; place-items: center; width: 28px; height: 24px; padding: 0; border: var(--line-w-thin) dashed var(--line-soft); border-radius: var(--r-xs); background: color-mix(in srgb, var(--paper-shade) 55%, transparent); color: var(--text-dim); box-shadow: var(--rung-face, 0 0 transparent), var(--rung-drop, 0 0 transparent); font-size: var(--t-label); }
.workshop-rung.is-owned { --rung-face: inset 2px 3px 0 var(--success-light), inset 0 -3px 0 var(--success-shade); --rung-drop: 0 2px 0 var(--shadow); border-style: solid; border-color: var(--line); background: var(--success); color: var(--text); }
.workshop-rung.is-next { --rung-face: var(--sunken); border-style: solid; border-color: var(--line); background: var(--recess); color: var(--text-invert); }
.workshop-rung.is-next.is-ready { --rung-face: inset 2px 3px 0 var(--accent-light), inset 0 -3px 0 var(--accent-tan); --rung-drop: 0 2px 0 var(--shadow); border-color: var(--line); background: var(--accent); color: var(--accent-text); }
.workshop-rung.is-selected { box-shadow: var(--rung-face, 0 0 transparent), 0 0 0 var(--line-w-thin) var(--paper), 0 0 0 4px var(--line), 0 2px 0 4px var(--shadow); }
.workshop-rung:active { translate: 0 1px; }
.workshop-stamp { padding: 3px 9px; border: var(--line-w) solid var(--danger-shade); border-radius: var(--r-xs); color: var(--danger-shade); font-size: var(--t-label); font-weight: 400; letter-spacing: var(--track-label); rotate: -8deg; }
.workshop-stamp[hidden] { display: none; }
.workshop-stamp.is-new { animation: workshop-stamp .4s steps(4) both; }
@keyframes workshop-stamp { 0% { scale: 2.4; opacity: 0; } 100% { scale: 1; opacity: 1; } }
.workshop-sheet h2 { margin: 10px 0 8px; font-size: var(--t-title); font-weight: 400; line-height: 1.15; letter-spacing: .02em; text-wrap: balance; }
.workshop-unlock { margin: 0 0 12px; padding: 8px 10px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-sm); background: var(--paper-alt); box-shadow: var(--sunken); }
.workshop-unlock span { display: block; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.workshop-unlock b { display: block; margin-top: 4px; font-family: var(--font-hand); font-size: var(--t-body); font-style: normal; font-weight: 400; line-height: 1.4; }
.workshop-sheet.is-installed .workshop-unlock { border-color: var(--success-shade); box-shadow: inset 4px 0 0 var(--success), var(--sunken); }
.workshop-sheet h3 { margin: 0 0 6px; color: var(--text-dim); font-size: var(--t-label); font-weight: 400; letter-spacing: var(--track-label); }
.workshop-needs ul { display: grid; gap: 6px; margin: 0 0 14px; padding: 0; list-style: none; }
.workshop-need { display: grid; grid-template-columns: minmax(0, 1fr) auto 30px; align-items: center; gap: 8px; padding: 6px 8px; border: var(--line-w-thin) solid var(--line-soft); border-radius: var(--r-sm); background: color-mix(in srgb, var(--paper-shade) 45%, transparent); }
.workshop-need b, .workshop-need small { display: block; }
.workshop-need b { font-size: var(--t-label); font-weight: 400; }
.workshop-need small { margin-top: 2px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.workshop-need-meter { display: flex; gap: 3px; }
.workshop-need-meter i { width: 9px; height: 12px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-xs); }
.workshop-need-meter i.is-on { background: var(--line); box-shadow: inset 0 2px 0 color-mix(in srgb, #fff 22%, transparent); }
.workshop-need.is-done { border-color: var(--success-shade); background: color-mix(in srgb, var(--success) 18%, transparent); }
.workshop-need.is-done .workshop-need-meter i { background: var(--success); box-shadow: inset 0 2px 0 var(--success-light); }
.workshop-need em { font-size: var(--t-label); font-style: normal; font-variant-numeric: tabular-nums; text-align: right; }
.workshop-tray { display: grid; grid-template-columns: repeat(auto-fill, var(--card-thumbnail-width)); justify-content: center; gap: 8px; }
.card-view--thumbnail { display: block; padding: 3px; border-width: var(--line-w-thin); }
.card-view--thumbnail .card-view-art { width: 100%; height: 100%; border-width: var(--line-w-hair); border-radius: var(--r-xs); }
.card-view--thumbnail .card-view-art canvas { width: 100%; height: auto; max-width: 100%; max-height: 100%; }
.card-view--thumbnail .card-view-emblem { font-size: 34px; }
.card-view--thumbnail .card-view-icons { position: absolute; inset: 5px; align-content: end; align-items: end; justify-content: end; flex-wrap: wrap; pointer-events: none; }
.card-view--thumbnail .card-view-icon { min-width: 16px; min-height: 16px; padding: 1px 3px; background: var(--paper); font-size: var(--t-micro); box-shadow: 0 1px 0 var(--shadow); }
.card-view--thumbnail.is-deep { --card-rim: var(--special); }
.card-view--thumbnail.is-spent { filter: saturate(.4); opacity: .75; }
.card-placeholder { display: grid; place-items: center; align-content: center; gap: 6px; width: var(--card-thumbnail-width); aspect-ratio: var(--card-ratio); border: var(--line-w-thin) dashed var(--line-soft); border-radius: var(--r-md); background: color-mix(in srgb, var(--paper-shade) 40%, transparent); box-shadow: var(--sunken); color: var(--text-dim); font-size: var(--t-title); font-weight: 400; }
.card-placeholder.is-deep { border-color: color-mix(in srgb, var(--special) 75%, var(--line)); color: color-mix(in srgb, var(--special) 75%, var(--line)); background: color-mix(in srgb, var(--special) 12%, transparent); }
.card-placeholder small { max-width: 100%; font-size: var(--t-meta); letter-spacing: var(--track-label); line-height: 1.3; text-align: center; white-space: normal; }
.workshop-payment-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; margin-bottom: 6px; }
.workshop-sheet .workshop-payment-head h3 { margin: 0; }
.workshop-reset, .workshop-picker-cancel { flex: none; padding: 5px 12px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: var(--surface-raised); color: var(--text); box-shadow: var(--cel), 0 2px 0 var(--shadow); font-size: var(--t-meta); letter-spacing: var(--track-label); text-transform: uppercase; }
.workshop-reset:active, .workshop-picker-cancel:active { translate: 0 2px; box-shadow: var(--cel); }
.workshop-reset[hidden], .workshop-picker[hidden], .workshop-picker-options[hidden], .workshop-picker-empty[hidden] { display: none; }
.workshop-pick { display: flex; min-width: 0; padding: 0; border-radius: var(--r-md); background: transparent; color: var(--text); text-align: left; }
.workshop-pick > .card-view { flex: 1; }
.workshop-pick:active > .card-view { translate: 0 2px; box-shadow: inset 0 0 0 var(--line-w-thin) var(--card-rim), var(--cel-paper), 0 1px 0 var(--shadow); }
.workshop-pick.is-swapping > .card-view { --card-rim: var(--accent); background: var(--paper-shade); }
.workshop-picker { margin-top: 10px; padding: 8px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-md); background: var(--paper-shade); box-shadow: var(--sunken); }
.workshop-picker header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.workshop-picker h4 { min-width: 0; margin: 0; font-size: var(--t-label); font-weight: 400; line-height: 1.3; overflow-wrap: anywhere; }
.workshop-picker-options { display: grid; grid-template-columns: repeat(auto-fill, var(--card-thumbnail-width)); justify-content: center; gap: 8px; }
.workshop-picker-empty { margin: 0; color: var(--danger-deep); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.45; text-wrap: pretty; }
.workshop-note { min-height: 30px; margin: 10px 0 14px; color: var(--text-dim); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.45; text-wrap: pretty; }
/* The one gold thing on this screen. Hold it and a brighter gold sweeps across. */
.workshop-install { position: relative; display: block; width: 100%; min-height: 54px; overflow: hidden; padding: 8px 13px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--accent); color: var(--accent-text); box-shadow: var(--cel-accent), 0 var(--drop) 0 var(--shadow); font-family: var(--font-ui); font-size: var(--t-label); font-weight: 400; letter-spacing: var(--track-label); text-transform: uppercase; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.workshop-install[hidden], .workshop-needs[hidden], .workshop-try[hidden] { display: none; }
.workshop-try { width: 100%; }
.workshop-install b { position: relative; font-weight: 400; }
.workshop-install-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--accent-light); box-shadow: inset 0 var(--band-light) 0 color-mix(in srgb, #fff 45%, transparent); transition: width .15s steps(3); }
.workshop-install.is-holding { translate: 0 var(--press); box-shadow: var(--cel-accent), 0 2px 0 var(--shadow); }
.workshop-install.is-holding .workshop-install-fill { width: 100%; transition: width var(--hold, 900ms) steps(12); }
.workshop-install:disabled { border-style: dashed; border-color: var(--line-soft); background: color-mix(in srgb, var(--paper-shade) 45%, transparent); color: var(--text-dim); box-shadow: none; cursor: default; }
@media (min-width:960px){
  .workshop-stage{flex:1 0 auto;display:grid;grid-template-columns:minmax(380px,520px) minmax(340px,420px);align-items:center;justify-content:center;gap:clamp(40px,6vw,88px);width:auto;margin:0;padding:36px 32px}
  .workshop-bench{height:290px}
  .bench-scope{scale:1.5}
  .workshop-slot{min-height:58px;padding:8px 10px}
  .workshop-slot small{font-size:var(--t-label)}
  .workshop-slot b{font-size:var(--t-title)}
}
@media (prefers-reduced-motion:reduce){.workshop-flash{display:none}.bench-part,.workshop-pips i,.workshop-stamp,.bench-mount.is-installed::after{animation:none!important}}


/* A tag under the readout: an ink chip punched into the sky, so its lettering stays inverted. */
.scope-readout em { --tag-rim: var(--special); display: block; margin-top: 6px; padding: 3px 9px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-pill); background: var(--recess); color: var(--text-invert); box-shadow: inset 0 0 0 var(--line-w-hair) var(--tag-rim), 0 2px 0 var(--shadow); font-size: var(--t-meta); font-style: normal; letter-spacing: var(--track-label); white-space: nowrap; }
.scope-readout em[hidden] { display: none; }
.scope-readout em i { display: block; margin-top: 2px; color: var(--success); font-style: normal; }

/* A note someone stuck on the glass. Always slightly crooked. */
.cozy-note { position: relative; max-width: 220px; padding: 16px 16px 12px; border: var(--line-w-thin) solid var(--line); border-radius: 4px 7px 5px 8px; background: var(--paper); color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.35; rotate: -3.5deg; box-shadow: var(--haze); }
.cozy-note::before { content: ""; position: absolute; top: -11px; left: 50%; width: 62px; height: 22px; translate: -50% 0; rotate: -7deg; border: var(--line-w-hair) solid color-mix(in srgb, var(--line) 30%, transparent); background: color-mix(in srgb, var(--metal-light) 62%, transparent); }
.cozy-note--tape-left::before { left: 26px; translate: none; rotate: -14deg; }

/* The hill's two changing notices are taped around the logo, with their state stamped in red ink. */
.contract-hint, .goal-hint { position: absolute; z-index: 3; display: block; width: min(46cqw, 190px); max-width: 190px; min-height: 94px; padding: 17px 14px 34px; text-align: left; }
.contract-hint { top: -102px; left: -10px; }
.goal-hint { right: -6px; bottom: -106px; rotate: 3deg; }
.contract-hint[hidden], .goal-hint[hidden] { display: none; }
.contract-hint:active { translate: 0 2px; rotate: -2.5deg; box-shadow: 0 3px 10px color-mix(in srgb, var(--shadow) 40%, transparent); }
.goal-hint:active { translate: 0 2px; rotate: 2deg; box-shadow: 0 3px 10px color-mix(in srgb, var(--shadow) 40%, transparent); }
.contract-hint-text small, .contract-hint-text b { display: block; overflow: hidden; }
.contract-hint-text small { color: var(--danger-deep); font-size: var(--t-meta); letter-spacing: var(--track-label); text-overflow: ellipsis; white-space: nowrap; }
.contract-hint-text b { display: -webkit-box; margin-top: 4px; font-size: var(--t-body); font-weight: 400; line-height: 1.25; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.goal-hint-text { min-width: 0; }
.goal-hint-text small, .goal-hint-text b { display: block; overflow: hidden; }
.goal-hint-text small { color: var(--danger-deep); font-size: var(--t-meta); font-weight: 400; letter-spacing: var(--track-label); }
.goal-hint-text b { display: -webkit-box; margin-top: 4px; color: var(--text); font-size: var(--t-body); font-weight: 400; line-height: 1.25; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.contract-hint-badge, .goal-hint-progress { position: absolute; right: 12px; bottom: 10px; padding: 3px 8px; border: 3px double var(--danger-deep); border-radius: var(--r-xs); color: var(--danger-deep); font-family: var(--font-ui); font-size: var(--t-meta); font-style: normal; font-weight: 400; font-variant-numeric: tabular-nums; letter-spacing: var(--track-label); line-height: 1; rotate: -7deg; }

.contract-screen, .contract-card-screen { overflow-y: auto; background: linear-gradient(135deg, var(--scene), var(--recess)); }
.contract-stage { flex: none; display: flex; flex-direction: column; gap: 18px; width: min(calc(100% - 32px), 460px); margin: 0 auto; padding-block: 18px max(28px, env(safe-area-inset-bottom)); }
/* A sheet of paper somebody handed you: hand-cut corners, faint rules, a haze grounding it on the night. */
.contract-letter { position: relative; padding: 16px 16px 18px; border: var(--line-w) solid var(--line); border-radius: var(--r-hand); background: var(--paper); color: var(--text); box-shadow: var(--cel-paper), var(--haze-lg); }
.contract-letter::before { content: ""; position: absolute; inset: 4px; border-radius: inherit; pointer-events: none; background: repeating-linear-gradient(0deg, transparent 0 21px, color-mix(in srgb, var(--line) 12%, transparent) 21px 22px); }
.contract-letter > * { position: relative; }
.contract-letterhead { display: flex; align-items: center; gap: 12px; padding-bottom: 11px; border-bottom: 4px double var(--danger-deep); }
.contract-seal { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--danger); color: var(--text); font-family: var(--font-ui); font-size: var(--t-title); line-height: 1; box-shadow: inset 3px 4px 0 var(--danger-light), inset 0 -4px 0 var(--danger-shade), 0 3px 0 var(--shadow); }
.contract-letterhead b, .contract-letterhead small { display: block; }
.contract-letterhead b { font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; letter-spacing: .03em; line-height: 1.1; text-wrap: balance; }
.contract-letterhead small { margin-top: 4px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
/* The prose is handwriting; only the letterhead, the term labels and the stamp are set in caps. */
.contract-date { min-height: 40px; margin: 10px 0 0; color: var(--text-dim); font-family: var(--font-hand); font-size: var(--t-body); text-align: right; }
.contract-subject { margin: 0 0 10px; font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; letter-spacing: .02em; }
.contract-salutation { margin: 0 0 4px; font-family: var(--font-hand); font-size: var(--t-body); }
.contract-body, .contract-closing { margin: 0 0 12px; font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.5; text-wrap: pretty; }
.contract-terms { margin: 0 0 12px; border-top: var(--line-w-thin) solid var(--line-soft); }
.contract-terms div { display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 10px; padding: 6px 2px; border-bottom: var(--line-w-hair) dashed var(--line-soft); }
.contract-terms dt { padding-top: 2px; color: var(--danger-deep); font-size: var(--t-meta); letter-spacing: var(--track-label); line-height: 1.2; }
.contract-terms dd { margin: 0; font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.35; overflow-wrap: anywhere; }
.contract-signatures { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.contract-signatures small, .contract-signatures b { display: block; }
.contract-signatures small { color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.contract-signatures b { min-height: 27px; margin-top: 3px; padding-bottom: 2px; border-bottom: var(--line-w-hair) dotted var(--line-soft); font-family: var(--font-hand); font-size: var(--t-title); font-weight: 400; line-height: 1.4; }
/* The observatory signs in its own ink. */
.contract-signature { color: var(--special-deep); }
/* Stamped, not printed: a crooked box of ink over the paper. */
.contract-stamp { position: absolute; top: 80px; left: 18px; padding: 4px 9px; border: 4px double var(--danger-deep); border-radius: var(--r-xs); color: var(--danger-deep); font-family: var(--font-ui); font-size: var(--t-title); font-weight: 400; letter-spacing: var(--track-label); rotate: -9deg; pointer-events: none; }
.contract-stamp[hidden] { display: none; }
.contract-stamp.is-new { animation: contract-stamp .4s steps(4) both; }
.contract-letter.is-returned .contract-stamp { border-color: var(--line-soft); color: var(--text-dim); }
@keyframes contract-stamp { 0% { scale: 2.4; opacity: 0; } 100% { scale: 1; opacity: 1; } }
.contract-actions { display: grid; gap: 12px; }
.contract-actions > [hidden] { display: none; }
/* The one gold thing on this screen: hold it and the red ink runs across the line. */
.contract-sign { position: relative; display: block; width: 100%; min-height: 56px; overflow: hidden; padding: 8px 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--accent); color: var(--accent-text); box-shadow: var(--cel-accent), 0 var(--drop) 0 var(--shadow); font-family: var(--font-ui); font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.contract-sign b { position: relative; font-weight: 400; }
.contract-sign-ink { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--danger); box-shadow: var(--cel-danger); transition: width .15s steps(3); }
.contract-sign.is-holding { translate: 0 var(--press); box-shadow: var(--cel-accent), 0 1px 0 var(--shadow); }
.contract-sign.is-holding .contract-sign-ink { width: 100%; transition: width var(--hold, 1100ms) steps(14); }

.contract-card-stage { flex: none; display: flex; flex-direction: column; gap: 18px; width: min(calc(100% - 40px), var(--card-full-width)); margin: 0 auto; padding-block: 22px max(28px, env(safe-area-inset-bottom)); }
/* The caption sits on the night, not on the card. */
.contract-card-caption { margin: 0; color: var(--text-invert-dim); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.5; text-align: center; }

.contract-notice { position: absolute; z-index: 30; left: 50%; top: max(12px, env(safe-area-inset-top)); width: min(calc(100% - 32px), 380px); translate: -50% 0; transition: top .2s steps(3); }
.contract-notice[hidden] { display: none; }
.achievement-notice:not([hidden]) ~ .contract-notice { top: calc(max(12px, env(safe-area-inset-top)) + 84px); }
/* A paper pill floating over a dark screen, so it carries an outline and a haze. */
.contract-notice button { --notice-cel: var(--cel-paper); display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px; width: 100%; padding: 9px 12px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--text); box-shadow: var(--notice-cel), var(--haze); text-align: left; }
.contract-notice button:active { translate: 0 var(--press); box-shadow: var(--notice-cel), 0 1px 0 var(--shadow); }
.contract-notice-seal { display: grid; place-items: center; width: 40px; height: 40px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--danger); color: var(--text); font-family: var(--font-ui); font-size: var(--t-title); line-height: 1; box-shadow: inset 0 0 0 3px var(--danger-shade), inset 3px 5px 0 var(--danger-light), inset 0 -6px 0 var(--danger-shade), 0 2px 0 var(--shadow); }
.contract-notice small, .contract-notice b { display: block; }
.contract-notice small { color: var(--danger-deep); font-size: var(--t-meta); letter-spacing: var(--track-label); }
.contract-notice b { margin-top: 4px; font-family: var(--font-hand); font-size: var(--t-body); font-weight: 400; line-height: 1.25; }
.contract-notice em { color: var(--text-dim); font-size: var(--t-title); font-style: normal; line-height: 1; }
.contract-notice.is-on { animation: contract-notice-in .36s steps(5, end) both; }
@keyframes contract-notice-in { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: none; } }

/* Both of these name a contract target: the loan sits on the timber topbar, the tag on the sky. */
.telescope-loan { color: var(--danger-deep); }
.scope-readout .scope-contract { --tag-rim: var(--danger); color: var(--text-invert); }

@media (min-width:960px){
  .contract-stage{width:min(calc(100% - 64px),540px);padding-block:36px}
  .contract-letter{padding:24px 26px 26px}
  .contract-stamp{top:84px;left:28px}
  .contract-terms div{grid-template-columns:104px minmax(0,1fr)}
  .contract-card-stage{padding-block:40px}
}
@media (max-height:700px){.contract-hint,.goal-hint{min-height:82px;padding-block:12px 30px}.contract-hint{top:-88px}.goal-hint{bottom:-90px}}
@media (orientation:landscape) and (max-width:959px) and (max-height:600px){.contract-hint{top:-80px}.goal-hint{bottom:-80px}}
@media (orientation:landscape) and (max-width:720px) and (max-height:600px){.goal-hint{right:-10px;width:145px}}
@media (prefers-reduced-motion:reduce){.contract-hint.is-letter .contract-hint-badge,.contract-stamp.is-new,.contract-notice.is-on{animation:none}.contract-notice{transition:none}}

.auth-guest { width: 100%; min-height: 44px; margin-top: 16px; border: var(--line-w-thin) dashed var(--line-soft); border-radius: var(--r-lg); background: transparent; color: var(--text-dim); font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; }
.auth-guest:active { translate: 0 2px; }
.auth-guest:disabled { opacity: .42; cursor: default; }

/* The sync line sits on the home screen's night sky, so it reads in paper, not ink. */
.sync-status { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 5px; margin: 0 0 clamp(4px, 1.4svh, 10px); color: var(--text-invert-dim); font-family: var(--font-hand); font-size: var(--t-meta); line-height: 1.5; }
.sync-status-link[hidden] { display: none; }
.sync-status-link { padding: 0; border: 0; border-bottom: var(--line-w-hair) solid currentColor; background: transparent; color: var(--accent); font-family: var(--font-ui); font-size: var(--t-meta); letter-spacing: var(--track-label); text-transform: uppercase; }
.sync-status-link:active { translate: 0 1px; }

/* Every notice is a paper toast dropped over the scene: outline, haze, ink text. */
.sync-notice { position: absolute; z-index: 30; left: 50%; top: max(12px, env(safe-area-inset-top)); display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 12px; width: min(calc(100% - 32px), 380px); padding: 11px 16px; border: var(--line-w) solid var(--line); border-radius: var(--r-pill); background: var(--paper); color: var(--text); box-shadow: var(--cel-paper), var(--haze); translate: -50% 0; transition: top .2s steps(3); }
.sync-notice[hidden] { display: none; }
.achievement-notice:not([hidden]) ~ .sync-notice, .contract-notice:not([hidden]) ~ .sync-notice { top: calc(max(12px, env(safe-area-inset-top)) + 84px); }
.achievement-notice:not([hidden]) ~ .contract-notice:not([hidden]) ~ .sync-notice { top: calc(max(12px, env(safe-area-inset-top)) + 168px); }
.sync-notice-mark { display: grid; place-items: center; width: 34px; height: 34px; border: var(--line-w-thin) solid var(--line); border-radius: 50%; background: var(--glass); color: var(--sky); font-size: 17px; line-height: 1; box-shadow: var(--sunken); }
.sync-notice b { font-size: var(--t-label); font-weight: 400; line-height: 1.3; }
.sync-notice.is-on { animation: sync-notice-in .36s steps(5, end) both; }
@keyframes sync-notice-in { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: none; } }

.sync-banner { position: absolute; z-index: 40; left: 50%; bottom: max(12px, env(safe-area-inset-bottom)); display: grid; gap: 11px; width: min(calc(100% - 32px), 420px); padding: 16px; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--surface); color: var(--text); box-shadow: var(--cel), var(--haze-lg); translate: -50% 0; }
.sync-banner[hidden] { display: none; }
.sync-banner p { margin: 0; color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.4; }
.sync-banner-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.sync-banner-actions .secondary-button { justify-content: center; min-height: 44px; padding-inline: 12px; background: var(--paper); font-size: var(--t-label); }

.sync-dialog { width: min(calc(100% - 32px), 460px); padding: 0; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--surface); color: var(--text); box-shadow: var(--cel), var(--haze-lg); }
.sync-dialog::backdrop { background: color-mix(in srgb, var(--shadow) 68%, transparent); }
.sync-dialog form { display: grid; gap: 13px; padding: clamp(18px, 5vw, 26px); }
.sync-dialog h2 { margin: 0; color: var(--text); font-family: var(--font-display); font-weight: 800; font-size: 24px; line-height: 1.1; letter-spacing: -.01em; }
.sync-dialog p { margin: 0; color: var(--text); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.45; }
.sync-dialog-counts { color: var(--text) !important; font-family: var(--font-ui) !important; letter-spacing: .04em; }
.sync-sides { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Two cards to choose between, so they are paper rather than another slab of teal. */
.sync-side { display: grid; align-content: start; gap: 5px; padding: 13px; border: var(--line-w-thin) solid var(--line); border-radius: var(--r-md); background: var(--paper); box-shadow: var(--cel-paper); }
.sync-side h3 { margin: 0 0 3px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); text-transform: uppercase; }
.sync-side b { color: var(--text); font-size: var(--t-title); font-weight: 400; }
.sync-side span { color: var(--text-dim); font-family: var(--font-hand); font-size: var(--t-body); }
.sync-side small { margin-top: 4px; color: var(--text-dim); font-size: var(--t-micro); letter-spacing: .1em; line-height: 1.8; }
.sync-side small em { color: var(--text); font-size: var(--t-meta); font-style: normal; letter-spacing: .04em; }
.sync-dialog-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin: 2px 0 0; padding: 0; }
.sync-dialog-actions .secondary-button { justify-content: center; min-height: 46px; padding-inline: 12px; background: var(--paper); font-size: var(--t-label); }
.sync-dialog-actions [hidden] { display: none; }
.sync-dialog-dismiss { grid-column: 1 / -1; min-height: 42px; border: var(--line-w-thin) dashed var(--line-soft); border-radius: var(--r-lg); background: transparent; color: var(--text-dim); font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; }
.sync-dialog-dismiss:active { translate: 0 2px; }
.account-form h3 { margin: 6px 0 -4px; color: var(--text-dim); font-size: var(--t-meta); letter-spacing: var(--track-label); text-transform: uppercase; }
.sync-dialog .account-status { min-height: 15px; margin: -4px 0; color: var(--danger-shade); font-family: var(--font-hand); font-size: var(--t-body); }
.sync-dialog .account-status.is-done { color: var(--text); }
.account-form :disabled { opacity: .42; cursor: default; }
@media (max-width:420px){.sync-sides,.sync-dialog-actions,.sync-banner-actions{grid-template-columns:1fr}}
@media (prefers-reduced-motion:reduce){.sync-notice.is-on{animation:none}.sync-notice{transition:none}}

.settings-dialog { width: min(calc(100% - 24px), 480px); max-height: min(760px, calc(100dvh - 24px)); padding: 0; overflow: auto; border: var(--line-w) solid var(--line); border-radius: var(--r-lg); background: var(--surface); color: var(--text); box-shadow: var(--cel), var(--haze-lg); }
.settings-dialog[open] { animation: settings-dialog-in var(--motion-page) var(--motion-bounce) both; }
.settings-dialog[open]::backdrop { background: color-mix(in srgb, var(--shadow) 72%, transparent); animation: settings-backdrop-in var(--motion-panel) var(--motion-ease) both; }
.settings-dialog.is-closing { pointer-events: none; animation: settings-dialog-out var(--motion-panel) var(--motion-ease) both; }
.settings-dialog.is-closing::backdrop { animation: settings-backdrop-out var(--motion-panel) var(--motion-ease) both; }
.settings-dialog[data-panel-direction="forward"] > section:not([hidden]) { animation: settings-panel-forward var(--motion-panel) var(--motion-ease) both; }
.settings-dialog[data-panel-direction="backward"] > section:not([hidden]) { animation: settings-panel-backward var(--motion-panel) var(--motion-ease) both; }
@keyframes settings-dialog-in { from { opacity: 0; translate: 0 20px; scale: .95; rotate: -.8deg; } to { opacity: 1; translate: 0; scale: 1; rotate: 0deg; } }
@keyframes settings-dialog-out { from { opacity: 1; translate: 0; scale: 1; } to { opacity: 0; translate: 0 14px; scale: .97; } }
@keyframes settings-backdrop-in { from { background: transparent; } }
@keyframes settings-backdrop-out { to { background: transparent; } }
@keyframes settings-panel-forward { from { opacity: 0; translate: 18px 0; } to { opacity: 1; translate: 0; } }
@keyframes settings-panel-backward { from { opacity: 0; translate: -18px 0; } to { opacity: 1; translate: 0; } }
.settings-dialog > section { padding: clamp(18px, 5vw, 26px); }
.settings-dialog > section[hidden] { display: none; }
.settings-dialog header { display: flex; align-items: start; justify-content: space-between; gap: 16px; margin-bottom: 15px; }
.settings-dialog h2 { margin: 2px 0 0; color: var(--text); font-family: var(--font-display); font-size: 28px; line-height: 1; }
.settings-dialog h3 { margin: 0; color: var(--text); font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; }
.settings-dialog p { margin: 0; color: var(--text-dim); font-family: var(--font-hand); font-size: var(--t-body); line-height: 1.42; }
.settings-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin: 18px 0; }
.settings-actions .secondary-button { justify-content: center; min-height: 46px; padding: 8px 12px; background: var(--paper); font-size: var(--t-label); }
.settings-file { position: relative; }
.settings-file input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.settings-feedback { min-height: 20px; color: var(--danger-shade) !important; }
.settings-links { display: grid; justify-items: center; gap: 5px; margin: 2px auto 12px; }
.settings-links a { color: var(--text-dim); font-family: var(--font-hand); font-size: var(--t-body); text-underline-offset: 3px; }
.settings-version { display: block; margin-top: 4px; color: var(--text-dim); font-family: var(--font-ui); font-size: var(--t-micro); letter-spacing: var(--track-label); text-align: center; text-transform: uppercase; }
@media (max-width:420px){.settings-actions{grid-template-columns:1fr}}
@media (prefers-reduced-motion:reduce){.settings-dialog[open],.settings-dialog[open]::backdrop,.settings-dialog>section:not([hidden]){animation:none!important}}

/* The painted backdrops from references/, compressed into assets/backgrounds/. A token cannot
   repaint a painting, so the art is a layer of its own with a shade over it: the shade is what
   keeps paper and ink readable whichever frame the art lands in. Only the three screens with a
   visible outdoors wear one — the album and the workbench are panels edge to edge, and a painting
   behind a panel is weight nobody sees. */
.home-screen { background: var(--scene); }
/* The art has its own ground, stars and horizon, so the drawn hill stands down. */
.home-screen::after { content: none; }
.home-sky { --backdrop: url("/assets/backgrounds/bg_portrait.webp"); inset: 0; background: var(--backdrop) center top / cover no-repeat; }
.home-sky::before { content: ""; position: absolute; inset: 0; background: linear-gradient(color-mix(in srgb, var(--shadow) 24%, transparent) 0%, transparent 20%, transparent 44%, color-mix(in srgb, var(--shadow) 36%, transparent) 100%); }
/* The moon the concept art puts over the menu; the backdrops leave that corner of sky open. */
.home-sky::after { top: 13%; }

.telescope-screen { --backdrop: url("/assets/backgrounds/bg_portrait.webp"); background: var(--backdrop) center top / cover no-repeat, var(--scene); }
.auth-gate { --backdrop: url("/assets/backgrounds/bg_portrait.webp"); background: linear-gradient(color-mix(in srgb, var(--shadow) 30%, transparent), color-mix(in srgb, var(--shadow) 45%, transparent)), var(--backdrop) center top / cover no-repeat, var(--scene); }

@media (orientation: landscape) {
  .home-sky, .telescope-screen, .auth-gate { --backdrop: url("/assets/backgrounds/bg_landscape.webp"); }
}

@media (hover: hover) and (pointer: fine) {
  .home-sky, .telescope-screen, .auth-gate { --backdrop: url("/assets/backgrounds/bg_large.webp"); }
}

/* The pen. Every outlined shape below draws a second line beside its own, and that line is drawn
   rather than computed: the wobble is baked into two small SVGs, hung on the ghost as a border
   image. Nine-slice is what makes one drawing fit every shape — the corners are placed at their own
   size and never stretch, and only the straight runs between them are pulled to length, so a 44px
   button and a 700px panel wear the same hand. The real outline never moves; all the wander lives
   in an ::after ghost, and text stays out of it.

   This used to bow the ghost through an SVG turbulence filter instead. It cost the album screen
   fifteen megapixels of fractal noise every time it opened, regenerated on the main thread on each
   repaint, which on iOS read as the whole game running in slow motion. A drawing costs one image
   decode and looks more like a pen than the filter did. */
:root {
  --pen: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg transform='translate(4,4)'%3E%3Cpath d='M23.48,0 L40.39,-0.40 L57.31,0.65 L74.23,1.11 L91.15,0.00 Q112,0 112,20.85 L112.73,37.33 L110.48,53.81 L112.41,70.29 L112.00,86.78 Q112,112 86.78,112 L70.14,113.12 L53.51,111.44 L36.88,113.13 L20.25,112.00 Q0,112 0,91.75 L-1.47,74.68 L0.89,57.61 L0.49,40.54 L0.00,23.48 Q0,0 23.48,0' fill='none' stroke='%2316273f' stroke-opacity='.5' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/svg%3E");
  --pen-sm: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56'%3E%3Cg transform='translate(3,3)'%3E%3Cpath d='M11.40,0 L18.41,-0.15 L25.42,1.14 L32.43,0.62 L39.43,0.00 Q50,0 50,10.57 L49.55,18.30 L49.46,26.04 L50.64,33.78 L50.00,41.51 Q50,50 41.51,50 L33.13,49.99 L24.76,49.25 L16.38,49.00 L8.00,50.00 Q0,50 0,42.00 L-1.07,34.35 L-0.87,26.70 L1.14,19.05 L0.00,11.40 Q0,0 11.40,0' fill='none' stroke='%2316273f' stroke-opacity='.5' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/svg%3E");
}

/* A ghost needs a positioned host, and the host owns that rather than the pen: promoting an element
   only while the pen is on would reshuffle paint order the moment the pen is switched off. A static
   host sends its ghost off to the nearest positioned ancestor, where it draws a line across the
   screen — which is exactly what happened before this rule existed. */
.card-button, .goal-slot, .workshop-slot, .empty-album, .sync-side { position: relative; }

[data-rough="on"] :is(
  .auth-panel, .primary-button, .secondary-button, .icon-button, .logout-button,
  .goal-slot, .goal-hint, .contract-letter,
  .workshop-sheet, .workshop-slot, .sync-side, .sync-dialog,
  .sync-banner, .sync-notice, .empty-album,
  .card-view, .contract-hint
)::after {
  content: "";
  position: absolute;
  box-sizing: border-box;
  inset: -3px;
  border: 30px solid transparent;
  border-image: var(--pen) 30 stretch;
  pointer-events: none;
}
/* Small chrome gets the smaller drawing: a 22px corner hung on a 40px button reads as a blob, and
   the nine-slice has to shrink its own bands to fit, which bends the corners out of shape. */
[data-rough="on"] :is(
  .primary-button, .secondary-button, .icon-button, .logout-button, .goal-hint,
  .contract-hint, .workshop-slot, .sync-notice
)::after {
  border-width: 14px;
  border-image: var(--pen-sm) 14 stretch;
}
/* A shape that clips its content shears an outside ghost flat, so these four draw theirs just
   inside the outline instead. */
[data-rough="on"] :is(.card-view, .contract-hint)::after { inset: 1px; }

/* The fork's orbital room is not Little Planets' painted hillside. Space lives inside the scope,
   where its Milky Way is rendered without the backdrop's decorative stars. */
#app .grocery-screen { background: linear-gradient(155deg, var(--night-800), var(--night-700) 56%, var(--night-600)); }
