/* Student page: a welcome page for signing in, then the studio. The composer stays beside the wall, so the place in the wall is
   never lost while editing. Cards sit on the grey page; a finished figure stays on white like the paper it is meant for. */

/* Welcome: the promise and sign-in on one side, a real figure on the other, details below.
   A technical figure must never be cropped or covered, and it stays on pure white in both themes, like the page it would print on. */
.welcome { min-height: 100svh; display: flex; flex-direction: column; }
.hero { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(32px, 4vw, 72px); width: min(1480px, 100%); height: clamp(640px, calc(100svh - 56px), 980px); margin: 0 auto; padding: 4px clamp(20px, 3vw, 44px) 28px; }
.hero-lead { display: flex; flex-direction: column; justify-content: center; justify-self: end; width: min(480px, 100%); min-width: 0; }
.eyebrow { font-size: var(--fs-m); font-weight: var(--bold); color: var(--ink-2); }
.hero-lead h1 { margin-top: 10px; font: var(--bold) var(--fs-xl)/1.1 var(--font-display); letter-spacing: var(--track-display); }

.signin { display: grid; gap: 12px; margin-top: 28px; padding: 20px; border-radius: var(--r-xl); background: var(--surface); box-shadow: var(--shadow-2); }
.signin-title { padding: 0 2px; }
/* One bordered group with a hairline between the fields, as on Apple ID. */
.signin-fields { border: 1px solid var(--line-2); border-radius: 14px; overflow: hidden; }
.signin-fields .input { border: 0; border-radius: 0; background: transparent; }
.signin-fields .input-wrap + .input-wrap { border-top: 1px solid var(--line-2); }
.signin-fields .input:focus { box-shadow: inset 0 0 0 2px var(--blue); }
.signin-foot { color: var(--ink-2); text-align: center; }

/* Floating label, as on Apple ID and Google sign-in. */
.float > .input { height: 56px; padding: 22px 42px 6px 15px; font-size: var(--fs-m); }
.float-label { position: absolute; left: 16px; top: 17px; font-size: var(--fs-m); line-height: 22px; color: var(--ink-3); pointer-events: none; transform-origin: left top; transition: transform 160ms var(--ease-out), color 120ms ease; }
.float > .input:focus ~ .float-label,
.float > .input:not(:placeholder-shown) ~ .float-label,
.float > .input:-webkit-autofill ~ .float-label { transform: translateY(-9px) scale(.824); }
.float > .input:focus ~ .float-label { color: var(--blue-text); }

.hero-stage { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 10px; min-height: 0; margin: 0; padding: 10px; border-radius: 28px; background: var(--surface); box-shadow: var(--shadow-3); }
.hero-prompt { display: grid; gap: 2px; padding: 10px 14px 11px; border-radius: 18px; background: var(--fill); }
.hero-prompt-label { font-weight: var(--bold); color: var(--ink-2); }
.hero-prompt-text { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hero-canvas { position: relative; min-height: 0; border-radius: 18px; background: #fff; overflow: hidden; }
.hero-canvas img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity 240ms ease; }
.hero-canvas img.loaded { opacity: 1; }
.hero-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap; padding: 0 8px 4px; color: var(--ink-2); }
.hero-meta b { font-weight: var(--bold); color: var(--ink); }

/* Details: cards of different sizes, each showing the thing it describes. */
.features { padding: clamp(48px, 7vw, 88px) clamp(16px, 3vw, 44px) clamp(48px, 6vw, 80px); scroll-margin-top: 40px; }
.features-inner { width: min(1240px, 100%); margin: 0 auto; }
.features h2 { margin-bottom: clamp(20px, 2.6vw, 32px); font: var(--bold) var(--fs-xl)/1.14 var(--font-display); letter-spacing: var(--track-display); }
.bento { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px; }
.card { grid-column: span 2; display: flex; flex-direction: column; gap: 18px; min-width: 0; padding: 26px; border-radius: var(--r-xl); overflow: hidden; }
.card-wide { grid-column: span 4; }
.card-text p { margin-top: 6px; font-size: var(--fs-m); line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.card-visual { margin-top: auto; }
/* The one dark card, in both themes: it redefines the tokens, so what sits inside just reads them. */
.card-dark { --surface: #1d1d1f; --ink: #f5f5f7; --ink-2: #a1a1a6; --fill-hover: rgb(255 255 255 / .14); --blue: #2997ff; color: var(--ink); }

.model-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3px; margin: 0; padding: 3px; list-style: none; border-radius: var(--r); background: var(--fill); }
.model-list li { display: grid; justify-items: center; gap: 1px; padding: 7px 4px 8px; border-radius: 10px; color: var(--ink-2); }
.model-list b { font-weight: var(--bold); color: var(--ink); }
.model-list li:nth-child(2) { background: var(--thumb); box-shadow: var(--shadow-thumb); }

/* Crops of the one login figure, so the page still downloads a single image. */
.crop { position: relative; overflow: hidden; border-radius: var(--r); background: #fff; box-shadow: 0 0 0 1px var(--line); }
.crop img { position: absolute; max-width: none; height: auto; }
.crop-a { aspect-ratio: 1536 / 680; }
.crop-a img { left: 0; top: 0; width: 100%; }
.crop-b { aspect-ratio: 800 / 820; }
.crop-b img { left: 0; top: -84.1%; width: 192%; }
.crop-square-a, .crop-square-b, .crop-square-c { aspect-ratio: 1; }
.crop-square-a img { left: -90.8%; top: -15.6%; width: 281.8%; }
.crop-square-b img { left: 0; top: -86.25%; width: 192%; }
.crop-square-c img { left: -123.9%; top: -114.2%; width: 229.3%; }

.demo-progress { display: grid; justify-items: center; gap: 22px; margin-block: auto; padding: 8px 0; }
.demo-progress .progress-time { font-size: var(--fs-xl); letter-spacing: var(--track-tight); }
.demo-progress .progress-time small { font-size: var(--fs-m); letter-spacing: 0; }
.demo-progress .progress-note { color: var(--blue); font-weight: var(--bold); }

.edit-demo { display: grid; gap: 10px; }
.bubble { justify-self: end; max-width: 92%; padding: 8px 14px; border-radius: 18px 18px 4px 18px; background: var(--fill); line-height: 1.45; }
.ref-demo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.ref-add { display: grid; place-items: center; aspect-ratio: 1; border-radius: var(--r); background: var(--fill); color: var(--ink-2); }
.ref-add .icon { width: 24px; height: 24px; }
.history-demo { display: grid; gap: 4px; }
.history-search { display: flex; align-items: center; gap: 8px; height: var(--h-s); margin-bottom: 6px; padding: 0 12px; border-radius: 980px; background: var(--fill); color: var(--ink-3); }
.history-row { display: grid; grid-template-columns: 72px minmax(0, 1fr) 16px; align-items: center; gap: 12px; padding: 8px 8px 8px 0; color: var(--ink-3); }
.history-row + .history-row { border-top: 1px solid var(--line); }
.history-row b { display: block; overflow: hidden; color: var(--ink); font-weight: var(--bold); text-overflow: ellipsis; white-space: nowrap; }
.history-row .crop { border-radius: 10px; }

.fine-print { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; padding: 26px; border-radius: var(--r-xl); }
.fine-print .icon { width: 20px; height: 20px; color: var(--ink-2); }
.fine-print h3 { margin-top: 10px; font: var(--bold) var(--fs-m)/1.35 var(--font-display); }
.fine-print p { margin-top: 4px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.site-footer { padding: 0 clamp(16px, 3vw, 44px) calc(28px + env(safe-area-inset-bottom, 0px)); color: var(--ink-3); text-align: center; }

/* Nav */
.quota { display: inline-flex; align-items: center; gap: 7px; height: var(--h-s); padding: 0 8px; }
.quota-text { color: var(--ink-2); }
.quota-count { font-weight: var(--bold); }
.quota-count .muted { font-weight: 400; }
#quota-ring { display: block; line-height: 0; }
.account { position: relative; display: grid; place-items: center; width: var(--h); height: var(--h); padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; transition: transform 160ms var(--ease-out); }
.account:active { transform: scale(.95); transition-duration: 100ms; }
.account[aria-expanded="true"] .avatar { box-shadow: 0 0 0 3px var(--blue-glow); }
.account .avatar, .account-who .avatar { background: var(--ink); color: var(--bg); }

.account-card { display: grid; gap: 14px; padding: 10px 10px 12px; }
.account-who { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 12px; align-items: center; }
.account-who b { display: block; font: var(--bold) var(--fs-m)/1.3 var(--font-display); overflow-wrap: anywhere; }
.account-who .note { color: var(--ink-2); }
.account-quota { display: grid; gap: 6px; color: var(--ink-2); }
.account-quota > div { display: flex; justify-content: space-between; gap: 8px; }

.banner { color: var(--ink); text-align: center; }

/* Layout */
.studio { display: grid; grid-template-columns: clamp(340px, 27vw, 400px) minmax(0, 1fr); gap: clamp(24px, 2.4vw, 36px); align-items: start; width: min(1560px, 100%); margin: 0 auto; padding: 0 clamp(16px, 2.2vw, 32px) calc(56px + env(safe-area-inset-bottom, 0px)); }

/* Create. Sticky and internally scrollable, with room inside the clip for the composer's shadow and focus glow. */
.create { position: sticky; top: var(--nav-h); display: grid; gap: 14px; max-height: calc(100dvh - var(--nav-h)); margin: 0 -8px; padding: 20px 8px 16px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
.create::-webkit-scrollbar { display: none; }
.greeting { display: grid; gap: 4px; padding: 0 4px 4px; }
.greeting h1 { line-height: 1.2; overflow-wrap: anywhere; }
.greeting p { font-size: var(--fs-m); color: var(--ink-2); }

.composer { display: grid; gap: 10px; padding: 12px; border-radius: var(--r-xl); background: var(--surface); box-shadow: var(--shadow-2); scroll-margin: calc(var(--nav-h) + 8px) 0 8px; transition: box-shadow 160ms ease; }
.composer:focus-within, .dragging .composer { box-shadow: var(--shadow-2), 0 0 0 1.5px var(--blue), 0 0 0 5px var(--blue-glow); }
/* Grows with the text up to the cap. refreshPrompt also gives height back when the column would overflow the screen. */
.prompt-input { display: block; width: 100%; min-height: 192px; max-height: 480px; padding: 6px 8px; border: 0; background: transparent; font-size: var(--fs-m); line-height: 1.55; resize: none; outline: none; overscroll-behavior: contain; }
.prompt-input::placeholder { color: var(--ink-3); }
/* Model picker: label over hint. */
.seg-stacked { --pad: 3px; display: grid; width: 100%; height: 56px; border-radius: var(--r); }
.seg-stacked::before { border-radius: 10px; }
.seg-stacked label { flex-direction: column; gap: 1px; padding: 0 4px; line-height: 1.25; }
.seg-stacked label:has(input:focus-visible) { border-radius: 10px; }
.seg-stacked label:has(input:checked) .seg-sub { color: var(--ink-2); }
.composer-bar { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; }
.prompt-count { padding: 0 6px; text-align: right; }
.prompt-count.warn { color: var(--err); }
.compose-message { padding: 0 4px; }
.compose-note { color: var(--ink-2); }
.compose-note:empty { display: none; }

.editing { display: grid; grid-template-columns: 44px minmax(0, 1fr) var(--h-s); align-items: center; gap: 12px; padding: 6px; border-radius: var(--r); background: var(--fill); }
.editing img { display: block; width: 44px; height: 44px; object-fit: cover; border-radius: var(--r-s); background: #fff; }
.editing-text { display: grid; gap: 1px; min-width: 0; line-height: 1.4; }
.editing-text b { font-weight: var(--bold); }

/* Reference images appear only once there are some. */
.refs { display: flex; gap: 8px; padding: 0 6px 2px; overflow-x: auto; }
.ref { position: relative; flex: none; width: 64px; height: 64px; border-radius: var(--r); overflow: hidden; background: var(--fill); transition: opacity 200ms ease, transform 200ms var(--ease-out); }
@starting-style { .ref { opacity: 0; transform: scale(.95); } }
.ref img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ref-remove { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: rgb(0 0 0 / .62); color: #fff; opacity: 0; cursor: pointer; transition: opacity 120ms ease, background-color 120ms ease; }
.ref-remove .icon { width: 12px; height: 12px; stroke-width: 2; }
.ref:focus-within .ref-remove { opacity: 1; }
.ref-remove:active { background: rgb(0 0 0 / .85); }
@media (hover: none) { .ref-remove { opacity: 1; } }

/* Example prompts: always exactly two rows of four, and they never submit by themselves. */
.examples { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; padding: 0 4px; }
.examples-label { grid-column: 1 / -1; margin-bottom: 2px; color: var(--ink-2); }
.example { min-width: 0; padding: 0 2px; font-weight: 400; }
.example .btn-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Gallery */
.gallery { min-width: 0; padding-top: 20px; }
.gallery-head { display: flex; align-items: center; gap: 10px; min-height: var(--h); margin-bottom: 14px; flex-wrap: wrap; }
.gallery-head h2 .muted { font-size: var(--fs-m); font-weight: 400; margin-left: 2px; letter-spacing: 0; }
.gallery-search { width: 188px; }
.gallery-search .input { height: var(--h-s); }
.conn:empty { display: none; }
.conn { display: inline-flex; align-items: center; gap: 6px; }
.conn::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--warn-fill); }

.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(228px, 100%), 1fr)); gap: 14px; transition: opacity 120ms ease; }
.tiles.dim { opacity: .55; }
.tile { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; overflow: hidden; transition: box-shadow 160ms ease; }
.tile.leaving { opacity: 0; transform: scale(.97); transition: opacity 160ms ease, transform 160ms var(--ease-out); }
.tile-media { position: relative; aspect-ratio: 1; background: var(--surface); overflow: hidden; isolation: isolate; }
.tile-open { position: absolute; inset: 0; display: block; width: 100%; height: 100%; padding: 0; border: 0; background: #fff; cursor: zoom-in; }
.tile-open:focus-visible { outline-offset: -3px; border-radius: var(--r-l); }
.tile-open img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 200ms ease; }
.tile-open img.loaded { opacity: 1; }
/* A finished image is the one moment worth a beat: it comes into focus. */
.tile-open img.reveal { animation: reveal 520ms var(--ease-out) both; }

/* Actions float over the image and only show when wanted, so the wall stays about the pictures. */
.tile-actions { position: absolute; z-index: 1; left: 8px; right: 8px; bottom: 8px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--h-s); gap: 6px; opacity: 0; transition: opacity 120ms ease; }
.tile-actions.always { grid-template-columns: minmax(0, 1fr); }
.tile-actions.always, .outcome ~ .tile-actions, .tile:focus-within .tile-actions { opacity: 1; }
.tile-actions .span-2 { grid-column: span 2; }
.tile-actions .btn { min-width: 0; padding: 0 6px; }
/* Over a figure the buttons need a ground of their own. Solid rather than blurred: one blur per tile is costly while scrolling. */
.tile-open ~ .tile-actions .btn, .progress ~ .tile-actions .btn { background: rgb(255 255 255 / .92); color: #1d1d1f; box-shadow: 0 1px 3px rgb(0 0 0 / .16), 0 0 0 .5px rgb(0 0 0 / .06); }
.tile-open ~ .tile-actions .btn:active, .progress ~ .tile-actions .btn:active { background: rgb(255 255 255 / .96); }
/* Touch has no hover: keep only the menu button, which offers the same actions. */
@media (hover: none) {
  .tile-actions { opacity: 1; left: auto; grid-template-columns: var(--h-s); }
  .tile-actions.always { left: 8px; }
  .tile-actions .btn:not(.tile-more, .tile-cancel) { display: none; }
}

.tile-caption { display: grid; align-content: start; gap: 2px; padding: 10px 14px 12px; min-width: 0; border-top: 1px solid var(--line); }
.tile-prompt { line-height: 1.45; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile-prompt.placeholder { color: var(--ink-3); }
.tile-meta { display: flex; align-items: center; gap: 6px; color: var(--ink-3); white-space: nowrap; overflow: hidden; }
.tile-meta-text { overflow: hidden; text-overflow: ellipsis; }
.tile-meta .status { flex: none; }

/* Progress: the ring carries the running estimate, one word says what is happening. */
.progress { position: absolute; inset: 0; display: grid; align-content: center; justify-items: center; gap: 10px; padding: 14px; background: var(--surface); text-align: center; }
.progress-ring { position: relative; display: grid; place-items: center; width: 96px; height: 96px; }
.progress-ring.demo-ring { width: 176px; height: 176px; }
.progress-ring .ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.progress[data-status="queued"] .ring { animation: spin 1.6s linear infinite; }
.progress-time { position: relative; font: var(--bold) var(--fs-l)/1 var(--font-display); font-variant-numeric: tabular-nums; }
.progress-time small { margin-left: 2px; font: 400 var(--fs-s) var(--font); color: var(--ink-2); }
.progress[data-status="queued"] .progress-time { font-size: var(--fs-m); }
.progress-note { font-size: var(--fs-m); color: var(--ink-2); }

/* A failure is information, not an alarm. */
.outcome { position: absolute; inset: 0; display: grid; align-content: center; justify-items: center; gap: 4px; padding: 18px 18px 52px; text-align: center; background: var(--surface); }
.outcome .icon { width: 22px; height: 22px; margin-bottom: 6px; color: var(--ink-3); }
.outcome b { font-weight: var(--bold); }
.outcome span { line-height: 1.55; color: var(--ink-2); overflow-wrap: anywhere; }

.empty { display: grid; justify-items: center; gap: 4px; padding: clamp(32px, 6vh, 64px) 24px; border-radius: var(--r-xl); text-align: center; }
.empty b { font: var(--bold) var(--fs-l)/1.4 var(--font-display); }
.empty-figure { display: block; width: min(280px, 72%); aspect-ratio: 1; margin-bottom: 18px; border-radius: var(--r); background: #fff; box-shadow: 0 0 0 1px var(--line); }
.empty.filtered .empty-figure { display: none; }
.more { margin-top: 24px; }

/* Viewer: the figure on a dark stage, like a photo app; details on the plain panel beside it. */
.viewer { width: min(1280px, calc(100vw - 48px)); }
/* A definite height, so a 3000-character prompt scrolls inside the panel instead of pushing the actions out of reach. */
.viewer-panel { width: 100%; height: min(calc(100dvh - 48px), calc(min(1280px, 100vw - 48px) - 400px)); padding: 0; gap: 0; grid-template-columns: minmax(0, 1fr) 400px; grid-template-rows: minmax(0, 1fr); overflow: hidden; }
.viewer-stage { position: relative; min-height: 0; background: var(--stage); touch-action: none; overflow: hidden; }
/* Out of flow, so the stage height is always definite and a figure is letterboxed, never cropped. */
.viewer-stage img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: contain; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.viewer-stage.swiping img { will-change: transform; }
.viewer-stage.swiping + .viewer-side { will-change: opacity; }
.viewer-nav { position: absolute; top: 50%; margin-top: calc(var(--h) / -2); background: rgb(40 40 44 / .72); color: #fff; -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: 0 0 0 .5px rgb(255 255 255 / .14); }
.viewer-nav:active { background: rgb(70 70 74 / .8); }
.viewer-nav.prev { left: 14px; }
.viewer-nav.next { right: 14px; }
.viewer-nav:disabled { display: none; }
/* Swiping replaces these on touch. */
@media (hover: none) { .viewer-nav { display: none; } }
.viewer-side { display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto; gap: 16px; padding: 16px 24px 24px; min-height: 0; }
.viewer-top { display: flex; align-items: center; justify-content: space-between; }
.viewer-prompt { font-size: var(--fs-m); line-height: 1.65; overflow: auto; overflow-wrap: anywhere; white-space: pre-wrap; overscroll-behavior: contain; }
.viewer-meta { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; margin: 0; padding-top: 16px; border-top: 1px solid var(--line); font-size: var(--fs-m); }
.viewer-meta dt { color: var(--ink-3); }
.viewer-meta dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.viewer-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.viewer-actions .btn-primary { grid-column: 1 / -1; }
.viewer-actions .btn[hidden] + .btn { grid-column: 1 / -1; }

/* Opening from a tile: a copy of the figure flies above the panel, which only fades in around it. */
dialog.viewer.flying[open] > .viewer-panel { animation: fade-in 200ms ease both; }
.viewer.flying #viewer-image, .viewer.flying .viewer-nav { visibility: hidden; }
.viewer-flight { position: fixed; object-fit: contain; pointer-events: none; }

@keyframes reveal { from { opacity: 0; filter: blur(12px); transform: scale(1.02); } to { opacity: 1; filter: blur(0); transform: none; } }

@media (hover: hover) and (pointer: fine) {
  .account:hover .avatar { box-shadow: 0 0 0 3px var(--fill-hover); }
  .ref:hover .ref-remove { opacity: 1; }
  .ref-remove:hover { background: rgb(0 0 0 / .85); }
  .tile:hover { box-shadow: var(--shadow-2); }
  .tile:hover .tile-actions { opacity: 1; }
  .tile-open ~ .tile-actions .btn:hover, .progress ~ .tile-actions .btn:hover { background: #fff; }
  .viewer-nav:hover { background: rgb(70 70 74 / .8); }
}

/* Gentler, not zero: the image still arrives, without blur or movement. */
@media (prefers-reduced-motion: reduce) {
  .tile-open img.reveal { animation: fade-in 200ms ease both; }
}
@media (prefers-contrast: more) {
  .signin, .hero-stage { box-shadow: 0 0 0 1px var(--ink); }
}

@media (max-width: 1040px) {
  .card { grid-column: span 3; }
  .card-wide, .card-dark { grid-column: 1 / -1; }
  .fine-print { grid-template-columns: minmax(0, 1fr); gap: 18px; }
}
/* Narrow windows read top to bottom: greeting, composer, then the wall. */
@media (max-width: 900px) {
  .studio { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .create { position: static; max-height: none; margin: 0; padding: 16px 0 8px; overflow: visible; }
  .prompt-input { min-height: 144px; max-height: min(480px, 60dvh); }
  .gallery { padding-top: 16px; }
}
/* Phones read top to bottom: the promise, the sign-in form, then the figure and details. */
@media (max-width: 860px) {
  .hero { grid-template-columns: minmax(0, 1fr); height: auto; gap: 24px; padding: 8px 16px 8px; }
  .hero-lead { justify-self: center; width: min(520px, 100%); }
  .hero-stage { width: min(640px, 100%); margin: 0 auto; grid-template-rows: auto auto auto; }
  .hero-canvas { aspect-ratio: 1; }
  .hero-meta { display: grid; gap: 1px; }
}
@media (max-width: 760px) {
  .quota-text { display: none; }
  .banner { padding: 10px 16px; }
  .gallery-head .chips { flex: 1 1 auto; }
  .gallery-search { width: 100%; order: 3; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .tile { border-radius: 14px; }
  .tile-caption { padding: 8px 10px 10px; }
  .progress { padding: 10px; }
  .progress-ring { width: 84px; height: 84px; }
  /* A phone viewer fills the screen: the figure on black, a sheet of details below. Drag the figure down to dismiss. */
  dialog.viewer { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; }
  dialog.viewer::backdrop { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .viewer-panel { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; height: 100%; border-radius: 0; background: var(--stage); }
  .viewer-stage { padding-top: env(safe-area-inset-top, 0px); }
  .viewer-side { max-height: 56dvh; padding: 8px 16px calc(14px + env(safe-area-inset-bottom, 0px)); gap: 10px; border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--surface); }
  .viewer-meta { padding-top: 10px; gap: 4px 14px; }
}
@media (max-width: 620px) {
  .card { grid-column: 1 / -1; padding: 22px 20px; }
  .bento { gap: 12px; }
  .fine-print { padding: 22px 20px; }
  .ref-demo { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
