:root {
  --black: #000000;
  --cream: #f7f5ef;
  --paper: #f3efe6;
  --green: #5d6d61;
  --green-dark: #445348;
  --tan: #b68a63;
  --rust: #8f4d2b;
  --muted: #6f716b;
  --line: rgba(0, 0, 0, 0.13);
  --line-soft: rgba(0, 0, 0, 0.08);
  --white: #fffdf8;
  --shadow: 0 24px 70px rgba(0, 0, 0, 0.12);
  --radius: 8px;
  --display: Fraunces, Georgia, serif;
  /* Editorial headline face, matching the homepage. --display stays Fraunces
     for the brand mark and frame art, which must keep matching real output. */
  --headline: "DM Serif Display", Georgia, serif;
  --ui: Inter, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; background: var(--paper); }
body {
  margin: 0;
  background:
    linear-gradient(rgba(93, 109, 97, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(93, 109, 97, 0.04) 1px, transparent 1px),
    var(--paper);
  background-size: 48px 48px;
  color: var(--black);
  font-family: var(--ui);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }
canvas { display: block; max-width: 100%; }

/* One line, left-aligned to the same gutter as the workspace below it, so
   the tool starts where the eye already is. This block used to be a centred
   lockup plus a display title plus a two-line pitch — 174px, a quarter of a
   laptop screen, spent restating the brand that sits 20px above it in the
   shell bar. The narrow breakpoint had already dropped the lockup and the
   pitch; desktop just never caught up. */
.site-header {
  margin: 0 auto;
  max-width: 1180px;
  padding: 20px 24px 0;
}
.eyebrow {
  color: var(--tan);
  display: block;
  font-family: Archivo, var(--ui);
  font-variation-settings: "wdth" 76;
  font-size: 0.86rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  margin: 0 0 0.7rem;
  text-transform: uppercase;
}
.studio-title,
.section-heading h2,
.email-band h2,
.control-card h2,
.action-modal h2 {
  font-family: var(--headline);
  /* DM Serif Display ships weight 400 only; anything heavier is faked. */
  font-weight: 400;
  letter-spacing: 0;
}
.studio-title {
  /* Sized to read as a page label rather than a hero. */
  font-size: clamp(1.5rem, 2.2vw, 1.9rem);
  /* Not 700 — DM Serif Display has one weight and the rest is faked. */
  font-weight: 400;
  line-height: 1;
  margin: 0;
}
.studio-title em {
  color: var(--green);
  font-style: italic;
  /* DM Serif Display's italic is 400 only. */
  font-weight: 400;
}

.button {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 5px;
  display: inline-flex;
  font-weight: 800;
  gap: 0.5rem;
  justify-content: center;
  min-height: 42px;
  padding: 0.72rem 1rem;
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
.button:hover { transform: translateY(-1px); }
.button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid rgba(93, 109, 97, 0.32);
  outline-offset: 2px;
}
.button-primary {
  background: var(--green);
  color: var(--cream);
}
.button-primary:hover { background: var(--green-dark); }
.button-secondary {
  background: var(--white);
  border-color: rgba(93, 109, 97, 0.32);
  color: var(--green-dark);
}
.button-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--black);
}

.studio-shell,
.email-band,
.site-footer,
.debug-panel {
  margin: 0 auto;
  max-width: 1180px;
  padding: 20px 24px 44px;
}
/* The title now shares the workspace's column, so the gap between them is a
   heading's gap, not a section break. */
.studio-shell { padding-top: 14px; }
.studio-grid {
  align-items: start;
  display: grid;
  gap: 24px;
  grid-template-columns: minmax(0, 1fr) minmax(420px, 500px);
}
.preview-panel {
  background: var(--white);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  order: 2;
  padding: 18px;
  position: sticky;
  top: 18px;
}
.controls-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
  order: 1;
}
.format-tabs {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(3, 1fr);
  margin-bottom: 10px;
}
.format-tab {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  color: var(--black);
  font-size: 0.88rem;
  font-weight: 800;
  min-height: 48px;
  padding: 0.52rem 0.5rem;
}
.format-tab span {
  color: var(--muted);
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
}
.format-tab.is-active {
  background: var(--green);
  color: var(--cream);
}
.format-tab.is-active span { color: rgba(247, 245, 239, 0.78); }

.canvas-wrap {
  align-items: center;
  background: #d8ddd5;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 6px;
  display: grid;
  min-height: 520px;
  overflow: hidden;
  padding: 18px;
  position: relative;
}
#previewCanvas {
  background: #f7f5ef;
  border-radius: 4px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.2);
  margin: auto;
  max-height: 66vh;
  touch-action: none;
}
.canvas-hint {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 700;
  margin: 10px 0 0;
  text-align: center;
}
.adjust-controls {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr auto;
  margin-top: 16px;
}
.adjust-controls label,
.words-grid label,
.submit-form label,
.email-form label,
.inline-email-form label {
  color: var(--muted);
  display: grid;
  font-size: 0.78rem;
  font-weight: 800;
  gap: 6px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
input, select, textarea {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--black);
  min-height: 42px;
  padding: 0.7rem 0.78rem;
  text-transform: none;
}
input[type="range"] {
  accent-color: var(--green);
  border: 0;
  padding: 0;
}
.preview-actions {
  display: grid;
  gap: 12px;
  grid-template-columns: 0.92fr 1.08fr;
  margin-top: 14px;
}
.download-main,
.surprise-main {
  width: 100%;
}

@media (min-width: 921px) {
  .preview-panel {
    padding: 14px;
    top: 12px;
  }
  .canvas-wrap {
    height: clamp(300px, calc(100vh - 370px), 500px);
    min-height: 0;
    padding: 12px;
  }
  #previewCanvas {
    height: auto;
    max-height: calc(100vh - 394px);
    max-width: 100%;
    width: auto;
  }
  .canvas-hint {
    margin-top: 7px;
  }
  .frame-nav {
    margin-top: 7px;
  }
  .frame-nav-btn {
    height: 32px;
    width: 32px;
  }
  .adjust-controls {
    gap: 10px;
    margin-top: 10px;
  }
  .adjust-controls label {
    gap: 2px;
  }
  .adjust-controls input[type="range"] {
    min-height: 30px;
  }
  .adjust-controls .button {
    min-height: 38px;
    padding-block: 0.5rem;
  }
  .preview-actions {
    gap: 10px;
    margin-top: 10px;
  }
  .preview-actions .button {
    min-height: 40px;
    padding-block: 0.56rem;
  }
}

.control-card {
  background: rgba(255, 253, 248, 0.88);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 20px;
}
.quiet-card {
  background: #ebe6dc;
}
.card-heading {
  align-items: start;
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}
.step-badge {
  border: 1px solid rgba(93, 109, 97, 0.45);
  border-radius: 999px;
  color: var(--green);
  display: grid;
  flex: 0 0 34px;
  font-weight: 800;
  height: 34px;
  place-items: center;
}
.control-card h2 {
  font-size: 1.35rem;
  margin: 0;
}
.control-card p {
  color: var(--muted);
  margin: 0.18rem 0 0;
}
.dropzone {
  background: var(--paper);
  border: 1.5px dashed rgba(93, 109, 97, 0.52);
  border-radius: var(--radius);
  color: var(--black);
  display: grid;
  gap: 6px;
  padding: 26px 18px;
  text-align: center;
  width: 100%;
}
.dropzone span {
  color: var(--muted);
  font-size: 0.9rem;
}
.dropzone.is-dragover {
  background: rgba(93, 109, 97, 0.12);
  border-color: var(--green);
}
.upload-status {
  font-size: 0.86rem;
  margin-top: 0.8rem !important;
}

.filter-label {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  margin: 16px 0 8px !important;
  text-transform: uppercase;
}
.frame-style-row {
  display: grid;
  gap: 10px;
  grid-template-columns: 1fr 1fr;
}
.style-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--black);
  display: grid;
  gap: 3px;
  padding: 12px;
  text-align: left;
}
.style-card span {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
}
.style-card.is-active {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(93, 109, 97, 0.15);
}
.filter-row,
.vibe-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.filter-pill,
.vibe-button {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--black);
  font-size: 0.82rem;
  font-weight: 800;
  padding: 0.5rem 0.72rem;
}
.filter-pill.is-active,
.vibe-button.is-active {
  background: var(--green);
  border-color: var(--green);
  color: var(--cream);
}

/* Refine chips are a second-order control — the six category pills above
   them are the primary way through the library. They were rendering at
   identical weight and size, so sixteen of them read as sixteen more
   category pills and swamped the panel. Same shape, quieter. */
.filter-row.is-secondary {
  gap: 6px;
}
.filter-row.is-secondary .filter-pill {
  border-color: var(--line-soft, var(--line));
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  padding: 0.32rem 0.6rem;
}
.filter-row.is-secondary .filter-pill.is-active {
  border-color: var(--green);
  color: var(--cream);
}
/* The number says how many, not what it is, so it sits behind the topic. */
.pill-count {
  font-variant-numeric: tabular-nums;
  margin-left: 0.35em;
  opacity: 0.55;
}
/* Closed, the whole block costs one line instead of four rows. */
.refine-toggle {
  background: none;
  border: 0;
  color: var(--green);
  display: block;
  font-family: Archivo, var(--ui);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  margin: 12px 0 0;
  padding: 0;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-transform: uppercase;
}
.refine-toggle[aria-expanded="true"] { margin-bottom: 8px; }
.campaign-strip {
  display: grid;
  gap: 10px;
  margin: 14px 0;
}
.campaign-card {
  background: #ebe6dc;
  border-left: 4px solid var(--green);
  border-radius: 6px;
  padding: 12px;
}
.campaign-card strong { display: block; }
.campaign-card span {
  color: var(--muted);
  font-size: 0.85rem;
}
.frame-nav {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: 36px 1fr 36px;
  margin-top: 10px;
}
.frame-nav-btn {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--green-dark);
  display: grid;
  font-size: 1.3rem;
  font-weight: 700;
  height: 36px;
  place-items: center;
  transition: background 0.15s ease;
  width: 36px;
}
.frame-nav-btn:hover { background: rgba(93, 109, 97, 0.1); }
.frame-nav-btn:disabled { cursor: default; opacity: 0.28; }
.frame-nav-label {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-align: center;
}

.results-row {
  align-items: center;
  display: flex;
  gap: 12px;
  justify-content: space-between;
  margin-top: 10px;
}
.frame-results-line {
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 700;
  margin: 0 !important;
}
.view-all-btn {
  font-size: 0.78rem;
  font-weight: 800;
  min-height: 28px;
  padding: 0.22rem 0.7rem;
  white-space: nowrap;
}

.frames-tray {
  align-items: stretch;
  display: grid;
  gap: 10px;
  grid-template-columns: minmax(0, 1fr);
  margin-top: 14px;
  min-height: 0;
}
.frames-tray.is-scrollable {
  grid-template-columns: 36px minmax(0, 1fr) 36px;
}
.frame-scroll-btn {
  align-self: stretch;
  background: var(--white);
  border: 1px solid rgba(93, 109, 97, 0.26);
  border-radius: var(--radius);
  color: var(--green-dark);
  display: grid;
  font-size: 2rem;
  font-weight: 700;
  min-height: 172px;
  place-items: center;
  transition: background 0.18s ease, opacity 0.18s ease;
}
.frame-scroll-btn:hover {
  background: rgba(93, 109, 97, 0.1);
}
.frame-scroll-btn:disabled {
  cursor: default;
  opacity: 0.34;
}
.frame-grid {
  display: grid;
  gap: 12px;
  grid-auto-flow: column;
  grid-auto-columns: minmax(142px, 34%);
  grid-template-columns: none;
  margin-top: 0;
  min-height: 0;
  overflow-x: auto;
  padding: 4px 4px 14px;
  scroll-snap-type: x proximity;
  scrollbar-color: rgba(93, 109, 97, 0.5) transparent;
}
.frames-tray.is-expanded {
  display: block;
}
.frames-tray.is-expanded .frame-scroll-btn {
  display: none;
}
.frames-tray.is-expanded .frame-grid {
  grid-auto-flow: row;
  grid-auto-columns: auto;
  grid-template-columns: repeat(3, 1fr);
  max-height: 560px;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  padding: 4px;
  scroll-snap-type: none;
  scrollbar-color: rgba(93, 109, 97, 0.5) transparent;
  -webkit-overflow-scrolling: touch;
}
.frame-card {
  background: var(--white);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  color: var(--black);
  display: grid;
  gap: 8px;
  padding: 10px;
  text-align: left;
  scroll-snap-align: start;
}
.frame-card.is-active {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(93, 109, 97, 0.16);
}
.frame-thumb {
  background: #dde0d8;
  border-radius: 5px;
  overflow: hidden;
  position: relative;
}
.new-badge {
  background: var(--green);
  border-radius: 999px;
  color: var(--cream);
  font-family: Archivo, var(--ui);
  font-variation-settings: "wdth" 76;
  font-size: 0.7rem;
  font-weight: 800;
  left: 7px;
  letter-spacing: 0.08em;
  padding: 0.18rem 0.5rem;
  position: absolute;
  text-transform: uppercase;
  top: 7px;
}
.frame-thumb canvas {
  aspect-ratio: 4 / 5;
  height: auto;
  width: 100%;
}
.frame-card strong { font-size: 0.94rem; }
.frame-meta {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
}
.words-grid {
  display: grid;
  gap: 12px;
}

.section-heading {
  max-width: 700px;
}
.section-heading h2,
.email-band h2 {
  font-size: clamp(2rem, 4vw, 3.6rem);
  line-height: 1;
  margin: 0;
}
.section-heading p {
  color: var(--muted);
}

.email-band {
  align-items: center;
  background: var(--black);
  border-radius: var(--radius);
  color: var(--cream);
  display: grid;
  gap: 18px;
  grid-template-columns: 1fr minmax(280px, 430px);
  margin-bottom: 34px;
}
.email-form,
.inline-email-form {
  display: grid;
  gap: 10px;
}
.email-form input,
.inline-email-form input {
  border-color: rgba(255, 255, 255, 0.18);
}
.site-footer {
  align-items: center;
  border-top: 1px solid var(--line-soft);
  color: var(--muted);
  display: flex;
  font-size: 0.9rem;
  justify-content: space-between;
  padding-top: 22px;
}

.toast {
  background: var(--black);
  border-radius: 999px;
  bottom: 22px;
  color: var(--cream);
  left: 50%;
  opacity: 0;
  padding: 0.7rem 1rem;
  pointer-events: none;
  position: fixed;
  transform: translate(-50%, 16px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 80;
}
.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

.action-modal {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  color: var(--black);
  /* dvh, not vh: on iOS the address bar is inside vh, so a modal sized to
     calc(100vh - 32px) is taller than the space it actually has. */
  max-height: calc(100dvh - 24px);
  max-width: min(760px, calc(100vw - 32px));
  overflow: auto;
  padding: 24px;
}

/* The column layout is scoped to [open], and must stay that way.
   Author styles beat the UA sheet whatever the specificity, so an
   unconditional `display: flex` here overrode `dialog:not([open])
   { display: none }` — the dialog closed but went on being drawn, so the
   X, Escape and the backdrop all looked broken. */
.action-modal[open] {
  /* Column layout so the preview is the thing that gives way when the
     screen is short. It used to hold 420px regardless and push the buttons
     below the fold — the finish screen is where every call to action lives,
     and they were only reachable by scrolling a dialog that did not look
     scrollable. */
  display: flex;
  flex-direction: column;
}
.action-modal::backdrop {
  background: rgba(0, 0, 0, 0.48);
}
.modal-close {
  background: transparent;
  border: 0;
  font-size: 1.8rem;
  line-height: 1;
  position: absolute;
  right: 18px;
  top: 12px;
}
.action-modal h2 { font-size: 2rem; margin: 0 2rem 0.5rem 0; }
.action-modal p { color: var(--muted); }
.ready-preview {
  background: #d8ddd5;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  display: block;
  margin: 12px auto 10px;
  max-height: 420px;
  object-fit: contain;
  width: min(100%, 360px);
  /* Shrinks first, down to a floor where it is still a picture of her frame
     rather than a thumbnail. min-height: 0 is what lets a flex item shrink
     below its content size at all. */
  flex: 0 1 auto;
  min-height: 120px;
  /* Long-press must stay available: it is how iOS saves straight to the
     camera roll, and the only save path inside in-app browsers. */
  -webkit-touch-callout: default;
  -webkit-user-select: auto;
  user-select: auto;
}
/* Shown as a caption rather than a readonly input: it is not editable, and
   as a field it looked fillable while taking a whole slot in a long form. */
.submit-frame-note {
  color: var(--muted);
  font-size: 0.82rem;
  margin: 0;
}
.submit-frame-note strong {
  color: var(--ink);
  font-weight: 700;
}
.save-hint {
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.4;
  margin: 0 auto 14px;
  max-width: 360px;
  text-align: center;
}
.save-hint strong {
  color: var(--ink);
  font-weight: 700;
}
.share-note {
  background: rgba(93, 109, 97, 0.1);
  border: 1px solid rgba(93, 109, 97, 0.2);
  border-radius: var(--radius);
  display: grid;
  gap: 4px;
  margin: 12px 0 14px;
  padding: 12px;
}
.share-note span {
  color: var(--muted);
}
.caption-box {
  color: var(--muted);
  display: grid;
  font-size: 0.78rem;
  font-weight: 800;
  gap: 8px;
  letter-spacing: 0.04em;
  margin-bottom: 14px;
  text-transform: uppercase;
}
.caption-box textarea {
  min-height: 104px;
}
.modal-actions {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, 1fr);
  /* Never the thing that gets squeezed out of view. */
  flex: 0 0 auto;
}
/* "Try Another Frame" is a different kind of action from the four above it —
   it leaves this screen rather than doing something with the picture — so it
   takes its own row instead of sitting orphaned in a half-width slot. */
.modal-actions > .button-ghost {
  grid-column: 1 / -1;
}

/* The ask, after the reward. Hidden until something has actually been saved
   or shared — and then it should read as the next thing to do, not as a
   footnote under the buttons. Every frame that goes out is an advert for
   the tool only if the caption says where it came from. */
.share-nudge {
  background: var(--green);
  border-radius: var(--radius);
  color: var(--cream);
  display: grid;
  flex: 0 0 auto;
  gap: 8px;
  justify-items: center;
  margin-top: 16px;
  padding: 18px 18px 20px;
  text-align: center;
}
.share-nudge-mascot {
  aspect-ratio: 12 / 5;
  border-radius: calc(var(--radius) - 4px);
  display: block;
  height: auto;
  margin-bottom: 2px;
  object-fit: cover;
  object-position: center;
  width: 100%;
}
/* Scoped past `.action-modal p { color: var(--muted) }`, which outranks a
   bare class and was painting both of these grey on green — 1.11:1, near
   enough invisible. Full cream is 5.04:1; the hierarchy between eyebrow,
   heading and body is carried by size and weight instead of by fading the
   text, which is the only way to have both on a dark panel. */
.share-nudge .share-nudge-eyebrow {
  color: var(--cream);
  font-family: Archivo, var(--ui);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  margin: 0;
  text-transform: uppercase;
}
.share-nudge strong {
  font-family: var(--headline);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.1;
}
.share-nudge .share-nudge-line {
  color: var(--cream);
  font-size: 0.88rem;
  line-height: 1.45;
  margin: 0;
  max-width: 46ch;
}
.share-nudge-tag {
  color: var(--cream);
  font-weight: 800;
  white-space: nowrap;
}
/* Where to post it. Built from GTH_SOCIAL, so an account we do not have
   leaves no logo behind. */
.share-nudge-social {
  display: flex;
  gap: 10px;
  margin-top: 2px;
}
.share-nudge-social:empty { display: none; }
.share-nudge-social-link {
  align-items: center;
  background: rgba(247, 245, 239, 0.12);
  border-radius: 999px;
  color: var(--cream);
  display: grid;
  height: 40px;
  place-items: center;
  transition: background 140ms ease;
  width: 40px;
}
.share-nudge-social-link:hover,
.share-nudge-social-link:focus-visible {
  background: rgba(247, 245, 239, 0.24);
}
.share-nudge-social-link svg {
  height: 20px;
  width: 20px;
}
.share-nudge-social-link svg.is-fill { fill: currentColor; stroke: none; }
.share-nudge-social-link svg.is-stroke {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}
/* Reversed out of the green, so the primary button cannot be green on green. */
.share-nudge .button {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--green);
  margin-top: 6px;
}

/* Saving completes the utility step. The same dialog then becomes a focused
   handoff: tag GTH first, submit the frame second, with the remaining paths
   still present but visually quieter. */
#postDownloadModal.is-share-step > h2,
#postDownloadModal.is-share-step > p,
#postDownloadModal.is-share-step .save-hint {
  display: none;
}
#postDownloadModal.is-share-step .ready-preview {
  display: none;
  order: 1;
}
#postDownloadModal.is-share-step .share-nudge {
  margin-top: 4px;
  order: 2;
}
#postDownloadModal.is-share-step .modal-actions {
  grid-template-columns: minmax(0, 1fr);
  margin-top: 10px;
  order: 3;
}
#postDownloadModal.is-share-step #savePhotoButton,
#postDownloadModal.is-share-step #modalDownloadButton,
#postDownloadModal.is-share-step #nativeShareButton {
  display: none;
}
#postDownloadModal.is-share-step #openSubmitButton {
  background: transparent;
  border: 2px solid var(--green);
  color: var(--green-dark);
  grid-column: 1 / -1;
  min-height: 50px;
}
#postDownloadModal.is-share-step #modalEmailButton {
  grid-column: 1 / -1;
  min-height: 50px;
  width: 100%;
}
#postDownloadModal.is-share-step .modal-actions > .button-ghost,
#postDownloadModal.is-share-step .modal-actions > .is-wide {
  grid-column: 1 / -1;
}
@media (prefers-reduced-motion: reduce) {
  .share-nudge-social-link { transition: none; }
}
.submit-form {
  display: grid;
  gap: 12px;
}
/* Marks the two fields we actually need. <abbr title> rather than a bare
   character so it is not read out as "star" with no explanation; the fields
   themselves carry the required attribute, which is what assistive tech
   announces. */
.req {
  border: 0;
  color: var(--rust);
  font-size: 1em;
  font-weight: 800;
  text-decoration: none;
}
.req-note {
  color: var(--muted);
  font-size: 0.8rem;
  letter-spacing: 0;
  margin: 0;
  text-transform: none;
}
.checkbox-row {
  align-items: start;
  display: flex !important;
  flex-direction: row;
  gap: 10px;
  letter-spacing: 0;
  text-transform: none;
}
.checkbox-row input { min-height: auto; margin-top: 4px; }
.checkbox-row a { color: var(--rust); font-weight: 800; }
.submit-success {
  background: var(--white);
  border: 1px solid rgba(93, 109, 97, 0.22);
  border-radius: var(--radius);
  margin-top: 16px;
  padding: 14px;
}

.debug-panel {
  background: var(--white);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  margin-bottom: 34px;
}
.debug-header {
  align-items: center;
  display: flex;
  justify-content: space-between;
}
.debug-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(4, 1fr);
}
.debug-card {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 12px;
}
.debug-card span {
  color: var(--muted);
  display: block;
  font-size: 0.78rem;
  font-weight: 800;
  text-transform: uppercase;
}
.debug-card strong {
  display: block;
  font-size: 1.7rem;
}
.debug-card ul {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}
.debug-card li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

@media (max-width: 920px) {
  .studio-grid {
    align-items: stretch;
    gap: 14px;
    grid-template-columns: 1fr;
  }
  .preview-panel,
  .controls-stack {
    display: contents;
  }
  .canvas-wrap {
    height: min(42dvh, 340px);
    min-height: 248px;
    order: -10;
    position: relative;
    box-shadow: 0 12px 28px rgba(27, 34, 29, 0.2);
  }
  #previewCanvas {
    max-height: calc(min(42dvh, 340px) - 36px);
    max-width: 100%;
  }
  .artist-bg-bar { order: -9; }
  .canvas-hint { order: -8; }
  .frame-nav { order: -7; }
  .adjust-controls { order: -6; }
  .preview-actions {
    order: -4;
  }
  .email-band { grid-template-columns: 1fr; }
  .debug-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .site-header {
    padding: 18px 18px 0;
  }
  .studio-title { font-size: clamp(1.6rem, 6vw, 2rem); }
  .studio-shell,
  .email-band,
  .site-footer,
  .debug-panel {
    padding: 30px 18px;
  }
  .studio-shell { padding-bottom: 30px; }
  .preview-panel,
  .control-card { padding: 14px; }
  .controls-stack .control-card:first-child {
    padding: 12px;
  }
  .controls-stack .control-card:first-child .card-heading {
    margin-bottom: 10px;
  }
  .controls-stack .control-card:first-child .dropzone {
    min-height: 96px;
    padding: 14px;
  }
  .canvas-wrap {
    border-radius: 12px;
    min-height: 220px;
    padding: 10px;
  }
  #previewCanvas { max-height: calc(min(42dvh, 340px) - 24px); }
  .canvas-hint { font-size: 0.72rem; }
  .adjust-controls,
  .debug-grid,
  .modal-actions {
    grid-template-columns: 1fr;
  }
  .frame-style-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .style-card {
    gap: 4px;
    min-height: 92px;
    padding: 12px 10px;
  }
  .style-card span {
    font-size: 0.74rem;
  }
  .preview-actions {
    gap: 8px;
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    margin-top: 12px;
  }
  .preview-actions .button {
    min-height: 46px;
    padding-inline: 0.7rem;
  }
  .preview-actions .button-secondary {
    font-size: 0.84rem;
  }
  .frame-grid { grid-auto-columns: minmax(132px, 72%); }
  .format-tabs {
    gap: 6px;
    margin-bottom: 0;
  }
  .site-footer {
    align-items: flex-start;
    flex-direction: column;
    gap: 8px;
  }
}
.artist-bg-bar {
  align-items: center;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
  padding: 14px 2px 4px;
}
.bg-mode-row {
  display: flex;
  gap: 8px;
}
.bg-mode-btn {
  background: rgba(0,0,0,0.06);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--black);
  font-size: 0.8rem;
  font-weight: 800;
  padding: 0.42rem 0.85rem;
}
.bg-mode-btn.is-active {
  background: var(--green);
  color: var(--cream);
}
.bg-swatch-row {
  display: flex;
  gap: 8px;
}
.bg-swatch {
  background: var(--swatch);
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  height: 30px;
  outline-offset: 2px;
  width: 30px;
}
.bg-swatch:first-child {
  box-shadow: 0 0 0 1px rgba(0,0,0,0.22);
}
.bg-swatch.is-active {
  outline: 2px solid var(--green);
}

/* ── The finish moment ───────────────────────────────────────
   She just made something. The sheet used to open as a list of
   chores — Download, Share, Submit, Join, Create Another — with
   the frame tucked under a heading. The frame leads now and
   arrives with a beat of its own, because the reward for making
   something should feel like one. Kept short: this is seen on
   every download, and a celebration that outstays its welcome
   becomes a delay. */
#postDownloadModal[open] .ready-preview {
  animation: frameArrive 520ms cubic-bezier(0.2, 0.9, 0.25, 1) both;
}

#postDownloadModal[open] h2 {
  animation: finishRise 380ms ease 180ms both;
}

#postDownloadModal[open] > p {
  animation: finishRise 380ms ease 250ms both;
}

#postDownloadModal[open] .save-hint {
  animation: finishRise 380ms ease 300ms both;
}

#postDownloadModal[open] .modal-actions {
  animation: finishRise 400ms ease 340ms both;
}

@keyframes frameArrive {
  from { opacity: 0; transform: scale(0.9) translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes finishRise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

#postDownloadModal h2 {
  text-align: center;
}

#postDownloadModal > p {
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  #postDownloadModal[open] .ready-preview,
  #postDownloadModal[open] h2,
  #postDownloadModal[open] > p,
  #postDownloadModal[open] .save-hint,
  #postDownloadModal[open] .modal-actions {
    animation: none;
  }
}

/* Search sits above the shelves: at a few hundred frames, typing "turkey"
   beats hunting through pills — especially on a phone. */
.frame-search {
  background: var(--bone, #faf4e9);
  border: 1px solid var(--line, rgba(31, 28, 20, .16));
  border-radius: 999px;
  color: inherit;
  font: inherit;
  font-size: .86rem;
  margin-bottom: .5rem;
  min-height: 40px;
  padding: 0 .9rem;
  width: 100%;
}
.frame-search:focus-visible {
  border-color: var(--field, #5d6d61);
  outline: 2px solid var(--field, #5d6d61);
  outline-offset: 1px;
}

/* Labels that exist for screen readers only. Without this they render as
   ordinary text — the search field's label was sitting beside it. */
.sr-only {
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* ── Collapsible browse panel ────────────────────────────────────
   Search, the shelves and four rows of tag chips run about 700px before the
   first thumbnail on a desktop. Useful when you are looking for something,
   in the way when you are not. */
.browse-toggle {
  align-items: center;
  background: none;
  border: 0;
  cursor: pointer;
  display: flex;
  gap: .45rem;
  padding: 0;
  width: 100%;
}
.browse-chev {
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  flex: none;
  height: 6px;
  opacity: .6;
  transform: rotate(45deg);
  transition: transform .18s ease;
  width: 6px;
}
.browse-toggle[aria-expanded="false"] .browse-chev { transform: rotate(-45deg); }
.browse-summary {
  font-weight: 600;
  letter-spacing: .02em;
  margin-left: auto;
  opacity: .62;
  text-transform: none;
}
#browsePanel[hidden] { display: none; }


/* The finish sheet carries more in it than any other modal — preview,
   heading, hint, six actions and now the tag ask — so it runs on a tighter
   rhythm than the shared modal styles give it. */
#postDownloadModal h2 { font-size: 1.6rem; margin-bottom: 0.25rem; }
/* :not(.save-hint) throughout — the hint is a direct <p> child too, and it
   carries the only instructions for getting the picture into the camera
   roll. It is the last thing that should be treated as decoration. */
#postDownloadModal > p:not(.save-hint) { font-size: 0.92rem; margin: 0 0 10px; }
#postDownloadModal .save-hint { margin-bottom: 10px; }

@media (max-height: 720px) {
  #postDownloadModal .ready-preview { max-height: 30dvh; margin-top: 4px; }
  #postDownloadModal h2 { font-size: 1.35rem; }
  /* On a short screen the sales line is the least load-bearing thing here;
     the buttons say what they do. */
  #postDownloadModal > p:not(.save-hint) { display: none; }
  #postDownloadModal .save-hint { font-size: 0.8rem; margin-bottom: 8px; }
}
