/* lumen. One theme, light: warm off-white and white, deep plum text, a rose
   accent. The frame right around the photo stays neutral grey, so the looks
   are judged against no tint. System fonts only; the page makes no request
   to anyone but itself. Contrast (WCAG) is noted beside each pair. */

:root {
  color-scheme: light;
  --bg: #fbf7f5;
  --surface: #ffffff;
  --surface-raised: #f6ecea;
  --border: #e8dad5; /* decorative dividers only */
  --border-strong: #968079; /* control outlines: 3.5:1 on --bg, 3.7:1 on --surface */
  --text: #2b1f24; /* 14.9:1 on --bg */
  --muted: #6b5960; /* 6.1:1 on --bg, 5.6:1 on --surface-raised, 5.4:1 on --stage */
  --accent: #c03a66; /* rose; 4.9:1 on --bg */
  --accent-strong: #9c2c52; /* hover, links: 6.8:1 on --bg */
  --accent-soft: #fce7ee; /* --accent-strong on it: 6.2:1 */
  --on-accent: #ffffff; /* 5.2:1 on --accent, 7.3:1 on --accent-strong */
  --stage: #ebeae9; /* neutral, untinted */
  --danger: #b42318; /* 5.8:1 on --danger-soft */
  --danger-soft: #fdecea;
  --focus: #c03a66;
  --radius: 14px;
  --radius-sm: 10px;
  --control: 2.75rem; /* 44px touch target */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body { margin: 0; }
/*
 * No double-tap zoom: two quick taps on a chip, a card, or a slider are two
 * taps. Pinch zoom stays, for anyone who needs larger text, except in the
 * full-screen editor and collage (below), where a pinch belongs to the photo.
 * On every element, not just the page: browsers stop looking up the tree at
 * the nearest scrolling strip or panel. :where() keeps it below every other
 * rule, so the canvases' own touch-action (none, for dragging) still holds.
 */
:where(*) { touch-action: manipulation; }
body {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font: 1rem/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
}
/*
 * The sandbox (app.js, markSandbox) carries a strip across the top of every
 * screen, the full-screen phone editor's too: fixed, above everything, with
 * the page and the app screens moved down by its height.
 */
body.sandbox { --sandbox-strip: calc(1.75rem + env(safe-area-inset-top)); padding-top: var(--sandbox-strip); }
.sandbox-strip {
  position: fixed; inset: 0 0 auto; z-index: 60; box-sizing: border-box; height: var(--sandbox-strip);
  display: flex; align-items: center; justify-content: center; margin: 0;
  padding: env(safe-area-inset-top) max(1rem, env(safe-area-inset-right)) 0 max(1rem, env(safe-area-inset-left));
  background: #f6d365; color: #3d2c00; font: 600 0.75rem/1.2 var(--font);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.sandbox .app-screen:not([hidden]) { top: var(--sandbox-strip); padding-top: 0; }
/* The whole sentence where it fits; a short one on phones. */
.sandbox-strip .short { display: none; }
@media (max-width: 40rem) {
  .sandbox-strip .long { display: none; }
  .sandbox-strip .short { display: inline; }
}
body.dragging main { outline: 2px dashed var(--accent); outline-offset: -0.75rem; border-radius: var(--radius); }

a { color: var(--accent-strong); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.skip { position: absolute; left: -999px; top: 0.5rem; z-index: 10; padding: 0.5rem 0.75rem; background: var(--surface-raised); border-radius: var(--radius-sm); }
.skip:focus { left: 0.5rem; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

header.site, footer.site, main {
  width: min(100%, 72rem); margin-inline: auto;
  /* Clear of a phone's notch when it is on its side (viewport-fit=cover). */
  padding-inline: max(1rem, env(safe-area-inset-left)) max(1rem, env(safe-area-inset-right));
}
header.site {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 1rem;
  /* Below the notch or Dynamic Island when lumen fills the screen. */
  padding-block: max(1rem, env(safe-area-inset-top)) 1rem;
}
.wordmark { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--text); text-decoration: none; font: 600 1.5rem/1 var(--font-display); letter-spacing: -0.02em; min-height: var(--control); }
.wordmark .dot { width: 0.7rem; height: 0.7rem; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #ffd9cc, #e8829f 55%, var(--accent)); }
.tagline { margin: 0; color: var(--muted); font-size: 0.875rem; }

main { flex: 1; padding-block: 1rem 2rem; }

/* Header: account navigation. */
.account-nav { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.header-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.collage { display: grid; gap: 1rem; }
.collage-canvas { display: block; max-width: 100%; max-height: min(70dvh, 52rem); width: auto; height: auto; touch-action: none; cursor: grab; border-radius: 4px; }
.collage-canvas:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.pick-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr)); gap: 0.5rem; max-height: 50dvh; overflow-y: auto; }
.pick { display: block; width: 100%; padding: 0; border: 2px solid transparent; border-radius: 8px; background: none; cursor: pointer; }
.pick:hover, .pick:focus-visible { border-color: var(--accent); }
.pick img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; background: var(--stage); }

/* Dialogs: sign-in and account. */
.sheet { border: 1px solid var(--border); border-radius: var(--radius); padding: 0; width: min(28rem, calc(100vw - 2rem)); background: var(--surface); color: var(--text); box-shadow: 0 20px 60px rgba(43, 31, 36, 0.18); }
.sheet::backdrop { background: rgba(43, 31, 36, 0.35); }
/* A tall dialog scrolls inside itself; its scrolling never moves the page behind it. */
.sheet { max-height: calc(100dvh - 2rem); overflow-y: auto; overscroll-behavior: contain; }
html:has(dialog[open]) { overflow: hidden; }
/* While a dialog is open the page is held where it was (app.js, holdPage). */
body.held { position: fixed; inset-inline: 0; width: 100%; }
.sheet-body { display: grid; gap: 0.85rem; padding: 1.25rem; }
.sheet h2 { margin: 0; font: 500 1.5rem/1.2 var(--font-display); }
.sheet .note { margin: 0; color: var(--muted); font-size: 0.875rem; line-height: 1.45; }
.sheet-body.flush { padding: 0; }
.sheet .or { display: flex; align-items: center; gap: 0.75rem; margin: 0; color: var(--muted); font-size: 0.8125rem; }
.sheet .or::before, .sheet .or::after { content: ""; flex: 1; border-top: 1px solid var(--border); }
.field { display: grid; gap: 0.35rem; font-weight: 600; font-size: 0.875rem; }
.field input { min-height: var(--control); padding: 0 0.75rem; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); font: 1rem var(--font); color: var(--text); background: var(--surface); }
.account-email { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.account-facts { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 1rem; margin: 0; font-size: 0.9375rem; }
.account-facts dt { color: var(--muted); }
.account-facts dd { margin: 0; }
.pro-offer { display: grid; gap: 0.5rem; padding: 0.85rem; background: var(--accent-soft); border-radius: var(--radius-sm); }
.pro-offer p { margin: 0; }
.danger-zone summary { cursor: pointer; color: var(--muted); font-size: 0.875rem; min-height: var(--control); display: flex; align-items: center; }
.danger-zone { display: grid; gap: 0.5rem; }
.button.danger { background: var(--surface); color: var(--danger); border-color: var(--danger); }
.button.danger:hover { background: var(--danger-soft); }

/* Gallery. */
.gallery { display: grid; gap: 1rem; }
.gallery-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; }
.gallery-head h1 { margin: 0; font: 500 clamp(1.75rem, 1.4rem + 1.5vw, 2.5rem)/1.1 var(--font-display); }
.gallery .note { margin: 0; color: var(--muted); }
.gallery-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 0.75rem; }
.gallery-grid li { display: grid; gap: 0.35rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.35rem; }
.gallery-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; background: var(--stage); display: block; }
.gallery-grid .row { justify-content: space-between; }
.gallery-grid .kind { color: var(--muted); font-size: 0.75rem; padding-left: 0.2rem; }
.photo-back { display: grid; grid-template-rows: 1fr auto auto; gap: 0.35rem; aspect-ratio: 1; padding: 0.5rem; border-radius: 6px; background: #f7f1e6; }
.photo-back[hidden], .gallery-grid img[hidden] { display: none; }
.photo-back textarea {
  width: 100%; height: 100%; resize: none; border: 0; background: transparent; color: #3b3036;
  /* 16px: smaller text makes iPhones zoom the page when it is tapped. */
  font: italic 1rem/1.45 Georgia, "Times New Roman", serif; padding: 0.25rem;
}
.photo-back textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-radius: 4px; }

/* Privacy and Terms. */
.legal { max-width: 46rem; line-height: 1.6; }
.legal h1 { font: 500 clamp(2rem, 1.6rem + 2vw, 3rem)/1.1 var(--font-display); margin: 1rem 0 0.25rem; }
.legal h2 { font-size: 1.125rem; margin: 2rem 0 0.5rem; }
.legal .updated { color: var(--muted); margin: 0; }
.operator { display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 1rem; }
.operator dt { color: var(--muted); }
.operator dd { margin: 0; }

/* Start */
.start { max-width: 40rem; margin: clamp(2rem, 10vh, 6rem) auto; text-align: center; }
.start h1 { margin: 0 0 1rem; font: 500 clamp(2.25rem, 1.5rem + 3.5vw, 3.75rem)/1.08 var(--font-display); letter-spacing: -0.03em; text-wrap: balance; }
.lead { margin: 0 auto 2rem; max-width: 32rem; color: var(--muted); font-size: 1.125rem; text-wrap: pretty; }
.hint { margin: 1rem 0 0; color: var(--muted); font-size: 0.875rem; }

/* Buttons */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: var(--control); padding: 0.5rem 1.1rem;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  font: 600 1rem/1.2 var(--font); cursor: pointer; text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease;
  -webkit-user-select: none; user-select: none; touch-action: manipulation;
}
.button.primary { background: var(--accent); color: var(--on-accent); }
.button.primary:hover { background: var(--accent-strong); }
.button.secondary { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); }
.button.secondary:hover { background: #f9d6e2; }
.button.ghost { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.button.ghost:hover { background: var(--surface-raised); }
.button.ghost[aria-pressed="true"] { background: var(--surface-raised); border-color: var(--text); }
.button.google { background: #fff; color: #1f1f1f; border-color: #747775; font-family: "Roboto", var(--font); font-weight: 500; }
.button.google:hover { background: #f8f9fa; }
.button.big { min-height: 3.25rem; padding-inline: 1.75rem; font-size: 1.125rem; }
.button:disabled { opacity: 0.5; cursor: default; }
input[type="file"]:focus-visible + .hint, .start label:has(+ input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }

/* Editor */
.editor { display: grid; gap: 1rem; }
@media (min-width: 60rem) {
  .editor { grid-template-columns: minmax(0, 1fr) 24rem; align-items: start; }
}
.stage { margin: 0; display: grid; place-items: center; gap: 0.5rem; padding: 0.75rem; background: var(--stage); border-radius: var(--radius); min-height: 12rem; }
.canvas-wrap { position: relative; display: grid; place-items: center; max-width: 100%; }
.paint { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; touch-action: none; border-radius: 4px; }
#view { display: block; max-width: 100%; max-height: min(70dvh, 52rem); width: auto; height: auto; border-radius: 4px; }
.status { color: var(--muted); font-size: 0.8125rem; font-variant-numeric: tabular-nums; min-height: 1.2em; }

.controls { display: grid; gap: 1rem; min-width: 0; }

/* Looks: a strip that scrolls inside itself on phones, a grid beside the photo on wide screens. */
.presets {
  display: grid; grid-auto-flow: column; grid-auto-columns: 5.25rem; gap: 0.5rem;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
  padding: 0.4rem 0.4rem 0.6rem;
  /* A little past the page's edge, so the first card's focus ring shows; but never into a notch's inset. */
  margin-left: max(-0.4rem, calc(env(safe-area-inset-left) - max(1rem, env(safe-area-inset-left))));
  margin-right: max(-0.4rem, calc(env(safe-area-inset-right) - max(1rem, env(safe-area-inset-right))));
}
@media (min-width: 60rem) {
  .presets { grid-auto-flow: row; grid-template-columns: repeat(4, 1fr); grid-auto-columns: auto; overflow: visible; }
}
.preset {
  display: grid; gap: 0.35rem; padding: 0.3rem; scroll-snap-align: start;
  background: var(--surface); color: var(--muted); border: 2px solid var(--border); border-radius: var(--radius-sm);
  font: 500 0.8125rem/1.2 var(--font); cursor: pointer; text-align: center;
}
.preset:hover { background: var(--surface-raised); color: var(--text); }
.preset canvas { display: block; width: 100%; aspect-ratio: 1; border-radius: 6px; background: var(--surface-raised); }
.preset span { padding-bottom: 0.15rem; overflow-wrap: anywhere; }
.preset[aria-checked="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); font-weight: 700; }
.panel { display: grid; gap: 0.5rem; min-width: 0; }
.group-title { margin: 0; font: 600 0.8125rem/1.2 var(--font); color: var(--muted); letter-spacing: 0.02em; text-transform: uppercase; }
.camera { position: relative; }
.camera .badge {
  position: absolute; top: 0.45rem; right: 0.45rem; padding: 0.1rem 0.35rem; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font: 700 0.6875rem/1.2 var(--font);
}
.field-label { font-weight: 600; font-size: 0.875rem; margin-top: 0.25rem; }
/* My presets: cards like the looks; the last one saves the current edit. */
.preset.mine { position: relative; }
.preset.mine .badge {
  position: absolute; top: 0.45rem; right: 0.45rem; padding: 0.1rem 0.35rem; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font: 700 0.6875rem/1.2 var(--font);
}
.preset.mine[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); font-weight: 700; }
.preset.mine.add { place-content: center; justify-items: center; border-style: dashed; color: var(--accent-strong); min-height: 7rem; }
.preset.mine.add .icon { width: 1.75rem; height: 1.75rem; }
.check { display: flex; align-items: center; gap: 0.6rem; min-height: var(--control); font-size: 0.9375rem; }
.check input { width: 1.25rem; height: 1.25rem; accent-color: var(--accent); }
.preset-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.preset-list li { display: flex; align-items: center; gap: 0.5rem; }
.preset-row-name { flex: 1; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.preset-list:empty { display: none; }

.strength { display: grid; grid-template-columns: 4.5rem 1fr 3.25rem; align-items: center; gap: 0.75rem; min-height: var(--control); color: var(--muted); font-size: 0.875rem; }
.strength output { color: var(--text); text-align: right; font-variant-numeric: tabular-nums; }
.strength input { width: 100%; min-height: var(--control); accent-color: var(--accent); }

.tools { display: grid; gap: 0.5rem; }
.tool { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.tool > summary {
  display: flex; align-items: center; justify-content: space-between; min-height: var(--control);
  padding: 0 0.75rem; cursor: pointer; font-weight: 600; list-style: none; border-radius: var(--radius-sm);
}
.tool > summary::-webkit-details-marker { display: none; }
.tool > summary::after { content: "+"; color: var(--muted); font-weight: 400; font-size: 1.25rem; }
.tool[open] > summary::after { content: "−"; }
.tool > summary:hover { background: var(--surface-raised); }
.tool-body { display: grid; gap: 0.5rem; padding: 0 0.75rem 0.75rem; }
.tool-body .note { margin: 0; color: var(--muted); font-size: 0.8125rem; line-height: 1.45; }
.sliders { display: grid; gap: 0.1rem; }
.row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  min-height: var(--control); min-width: 3.25rem; padding: 0 0.85rem; border-radius: var(--radius-full, 999px);
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); font: 600 0.875rem/1 var(--font); cursor: pointer;
}
.chip:hover { background: var(--surface-raised); }
.chip[style*="--swatch"] { display: inline-flex; align-items: center; gap: 0.4rem; }
.chip[style*="--swatch"]::before { content: ""; width: 0.9rem; height: 0.9rem; border-radius: 50%; background: var(--swatch); border: 1px solid var(--border-strong); }
/* An HSL band that has been changed carries a dot. */
.chip.changed::after { content: ""; width: 0.35rem; height: 0.35rem; border-radius: 50%; background: var(--accent); }
.chip[aria-checked="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.button.small { min-height: var(--control); padding: 0.4rem 0.8rem; font-size: 0.875rem; justify-self: start; }
.button.toggle[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
/* A secondary button is already pale rose, so its "on" is solid rose. */
.button.secondary.toggle[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.spot-controls { display: grid; gap: 0.25rem; }
#view.placing { cursor: crosshair; touch-action: none; }
.enhance { display: grid; gap: 0.4rem; padding: 0.75rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.enhance .note { margin: 0; color: var(--muted); font-size: 0.8125rem; line-height: 1.45; }
.actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.actions:not(:has(button:not([hidden]))) { display: none; }
.action-bar { display: flex; gap: 0.5rem; }
.action-bar .primary { flex: 1 1 auto; }
/* Undo and redo, at the start of the action bar. */
.history { display: flex; gap: 0.125rem; flex: none; }
/* With Share too, the row is full: compare and share keep only their icons (phones always, style.css "Phones"). */
.action-bar:has(#share:not([hidden])) :is(#compare, #share) { flex: none; padding-inline: 0.8rem; }
.action-bar:has(#share:not([hidden])) :is(#compare, #share) .label {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.icon-button:disabled { opacity: 0.35; cursor: default; background: none; }
/* Style match: the reference photo, small, beside its buttons. */
.match-row { align-items: center; }
.match-thumb { width: 3rem; height: 3rem; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border); }
/* Batch: progress, then each edited photo as a small square. */
#batch-progress { width: 100%; accent-color: var(--accent); }
.batch-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); gap: 0.4rem; margin: 0; padding: 0; list-style: none; }
.batch-list:empty { display: none; }
.batch-list img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-raised); }
.batch-photos { display: grid; gap: 0.5rem; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.batch-groups { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* A group already shared stays tappable (to share again) but reads as done. */
.batch-groups .button[data-done] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.batch-list .failed { display: grid; place-items: center; aspect-ratio: 1; padding: 0.25rem; border-radius: var(--radius-sm); background: var(--danger-soft); color: var(--danger); font-size: 0.6875rem; text-align: center; }
/* Long presses are ours: no "save image" menu over the photo or the compare button. */
#compare, #view, .collage-canvas { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }

/* Icons (icons.js): Material Symbols, in the colour of the text around them. */
.icon { width: 1.25em; height: 1.25em; flex: none; fill: currentColor; }
.icon-button {
  display: inline-grid; place-items: center; width: 2.75rem; height: 2.75rem; padding: 0;
  border: 0; border-radius: 999px; background: none; color: var(--text); cursor: pointer;
}
.icon-button:hover { background: var(--surface-raised); }
.icon-button .icon { width: 1.5rem; height: 1.5rem; }
.app-bar { display: flex; align-items: center; gap: 0.5rem; grid-column: 1 / -1; }
.app-title { margin: 0; font: 500 clamp(1.75rem, 1.4rem + 1.5vw, 2.5rem)/1.1 var(--font-display); }
.phone-only, .tooltabs, .tabbar { display: none; }
[data-panel][hidden] { display: none !important; }
.start-more { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-top: 1.25rem; }
/* Nothing to drop with a finger. */
@media (pointer: coarse) { .drop-hint { display: none; } }

/*
 * Wide screens: the photo stays beside the controls while they scroll, and
 * the actions (Download) stay at the bottom of their column.
 */
@media (min-width: 60rem) {
  .editor > .stage { position: sticky; top: 1rem; }
}
@media (min-width: 60rem) and (min-height: 33rem) {
  html:has(.app-screen:not([hidden])) { scroll-padding-bottom: 5.5rem; }
  .controls > .action-bar {
    order: 99; position: sticky; bottom: 0; z-index: 3;
    /* An iPad has a home indicator too. */
    padding: 0.6rem 0 calc(0.6rem + env(safe-area-inset-bottom)); background: var(--bg); border-top: 1px solid var(--border);
  }
}

/*
 * Phones, upright: laid out like a photo app. A tab bar at the bottom leads
 * to the main places, within a thumb's reach. The editor and the collage
 * fill the screen: a slim bar with Back, the photo as large as it fits, the
 * chosen tool's controls, a row of tool tabs, and the actions at the bottom,
 * clear of the home indicator. A phone on its side (short screens) keeps the
 * scrolling layout: there is no room for all of that.
 */
@media (max-width: 59.99rem) and (min-height: 33rem) {
  body { padding-bottom: calc(3.75rem + env(safe-area-inset-bottom)); }
  .header-actions { display: none; }
  .tabbar {
    display: flex; position: fixed; inset: auto 0 0 0; z-index: 10;
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    background: var(--surface); border-top: 1px solid var(--border);
  }
  .tabbar button, .tooltabs button {
    flex: 1 1 0; display: grid; justify-items: center; align-content: center; gap: 0.2rem;
    min-height: 3.75rem; padding: 0.4rem 0.25rem; border: 0; background: none;
    color: var(--muted); font: 600 0.75rem/1.1 var(--font); cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .tabbar button[hidden], .tooltabs button[hidden] { display: none; }
  .tabbar .icon, .tooltabs .icon { width: 1.5rem; height: 1.5rem; }
  .tabbar button[aria-current="page"], .tooltabs button[aria-pressed="true"] { color: var(--accent-strong); }
  .tabbar button:focus-visible, .tooltabs button:focus-visible { outline: 2px solid var(--focus); outline-offset: -4px; border-radius: 10px; }
  .start-more { display: grid; justify-content: stretch; }
  /* Dialogs rise from the bottom, as an app's sheets do, within a thumb's reach. */
  .sheet {
    width: 100%; max-width: none; margin: auto 0 0; max-height: 88dvh;
    border-radius: var(--radius) var(--radius) 0 0; border-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .start .button.big { width: 100%; }

  /* The editor and the collage: full screen. */
  body:has(.app-screen:not([hidden])) { overflow: hidden; padding-bottom: 0; }
  body:has(.app-screen:not([hidden])) :is(header.site, footer.site, .tabbar) { display: none; }
  .app-screen:not([hidden]) {
    position: fixed; inset: 0; z-index: 20; display: flex; flex-direction: column; gap: 0;
    /* Scroll the tool strips and panels, but never zoom the page. */
    touch-action: pan-x pan-y;
    padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
    background: var(--bg);
  }
  :where(.app-screen:not([hidden])) :where(*) { touch-action: pan-x pan-y; }
  .app-screen > .app-bar { display: flex; min-height: 3.25rem; padding: 0 0.5rem; }
  .app-screen .app-title { font-size: 1.375rem; }
  .app-screen > .stage {
    flex: 1 1 auto; min-height: 0; padding: 0.5rem; border-radius: 0;
    container-type: size; grid-template-rows: minmax(0, 1fr) auto;
  }
  .app-screen #view, .app-screen .collage-canvas { max-width: 100cqw; max-height: calc(100cqh - 2.25rem); }
  .app-screen > .controls { flex: none; display: flex; flex-direction: column; gap: 0; background: var(--bg); border-top: 1px solid var(--border); }
  .app-screen .tools { display: contents; }
  .app-screen [data-panel] { display: none; order: 1; }
  /* One height for every tool, so the photo keeps its size from tab to tab. */
  .app-screen [data-panel].active {
    /* Rows keep their full height (a scrolling strip would otherwise be squashed); the panel scrolls. */
    display: grid; align-content: start; grid-auto-rows: max-content; gap: 0.75rem; height: clamp(9.5rem, 30dvh, 16rem);
    overflow-y: auto; overscroll-behavior: contain; padding: 0.75rem 1rem;
  }
  .app-screen details[data-panel] { border: 0; border-radius: 0; background: none; }
  .app-screen details[data-panel] > summary, .app-screen .group-title { display: none; }
  /* The Looks tab holds two strips, so they are named, and the cards are a little smaller. */
  .app-screen #looks-panel .group-title { display: block; }
  .app-screen #looks-panel .presets { grid-auto-columns: 4.5rem; padding-block: 0.25rem 0.4rem; }
  .app-screen #looks-panel .preset { gap: 0.2rem; padding: 0.25rem; font-size: 0.75rem; }
  .app-screen .preset.mine.add { min-height: 0; }
  .app-screen details[data-panel] .tool-body { padding: 0; }
  .app-screen .tooltabs { display: flex; order: 2; overflow-x: auto; scrollbar-width: none; border-top: 1px solid var(--border); }
  .app-screen .tooltabs::-webkit-scrollbar { display: none; }
  /* A few tabs share the width; many scroll sideways. */
  .app-screen .tooltabs button { flex: 1 0 4.5rem; }
  .app-screen .controls > .action-bar {
    order: 3; padding: 0.5rem 1rem calc(0.5rem + env(safe-area-inset-bottom));
    border-top: 1px solid var(--border);
  }
  /* Undo, redo, compare, share, and download share one row: compare and share keep only their icons. */
  .app-screen .action-bar { align-items: center; }
  .app-screen .action-bar .history .icon-button { width: 2.5rem; }
  .app-screen .action-bar :is(#compare, #share) { flex: none; padding-inline: 0.8rem; }
  .app-screen .action-bar :is(#compare, #share) .label {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .app-screen .action-bar .primary { min-width: 0; }
  /* Errors show over the photo, where they are seen. */
  body:has(.app-screen:not([hidden])) .error {
    position: fixed; z-index: 30; margin: 0;
    inset: calc(3.5rem + env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) auto max(1rem, env(safe-area-inset-left));
  }
}

.error { max-width: 40rem; margin: 1rem auto 0; padding: 0.75rem 1rem; color: var(--danger); background: var(--danger-soft); border-radius: var(--radius-sm); text-align: center; }

footer.site { padding-block: 1.5rem max(2rem, calc(1rem + env(safe-area-inset-bottom))); color: var(--muted); font-size: 0.875rem; border-top: 1px solid var(--border); }
footer.site p { margin: 0.25rem 0; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; scroll-behavior: auto !important; }
}
