      /* Snailgram's own colours, taken from a snail and the post:
         lettuce is the loud brand field (hero and footer), ballpoint blue is the pen and anything you press,
         postmark red is stops and stamps, shell amber is envelopes, airmail blue is soft panels,
         envelope is the page and iron-gall ink is all text. */
      :root {
        color-scheme: light;
        --lettuce: #cdec5c;
        --lettuce-deep: #a9c93a;
        --violet: #2b3bd1;
        --violet-deep: #1f2c9e;
        --shell: #ffb547;
        --postmark: #e5482b;
        --shell-deep: #e8921c;
        --trail: #dde3fa;
        --night: #1a1f3a;
        --paper: #f2ecdf;
        --card: #fffdf8;
        --text: var(--night);
        --text-soft: #5a5d72;
        --line: #e2d9c6;
        --rule: #a39d8c;
        --error: #c0262d;
        --display: "Fraunces", Georgia, serif;
        --sans: "DM Sans", system-ui, sans-serif;
        --hand: "Nothing You Could Do", cursive;
        --ease: cubic-bezier(.2, .8, .2, 1);
        --spring: cubic-bezier(.3, 1.45, .5, 1);
        --banner-h: 34px;
        --header-h: calc(80px + var(--banner-h));
        --section-y: clamp(72px, min(11vw, 13vh), 144px);
        --r-paper: 4px;
        --r-control: 999px;
        --r-panel: 28px;
        /* Soft ink-tinted shadows: a close one and a wide one. */
        --shadow-paper: 0 1px 2px rgba(26, 31, 58, .12), 0 14px 30px -18px rgba(26, 31, 58, .5);
        --shadow-lift: 0 2px 4px rgba(26, 31, 58, .12), 0 34px 56px -26px rgba(26, 31, 58, .6);
        --shadow-press: 0 8px 18px -8px rgba(43, 59, 209, .7);
        /* Brand marks: the spiral shell (from the logo) and the dotted trail a snail leaves. */
        --trail-dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 80'%3E%3Cpath d='M0 40 C80 10 160 70 240 40 S400 10 480 40' fill='none' stroke='%23fffdf8' stroke-width='6' stroke-linecap='round' stroke-dasharray='0 17'/%3E%3C/svg%3E");
        /* The snail trail: ballpoint into lettuce into postmark, like an airmail edge. */
        --trail-band: linear-gradient(90deg, var(--violet), var(--lettuce) 50%, var(--postmark));
        /* Paper tooth: a static noise tile, rasterised once. */
        --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .11 0 0 0 0 .09 0 0 0 0 .27 .1 0 0 0 -.025'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
        background: var(--paper);
        color: var(--text);
        font-family: var(--sans);
        font-size: 17px;
        line-height: 1.6;
      }

      * { box-sizing: border-box; }
      html { overflow-x: hidden; }
      body { margin: 0; background: var(--paper); overflow-x: clip; -webkit-font-smoothing: antialiased; }
      a { color: inherit; }
      ::selection { background: var(--lettuce); color: var(--night); }
      :focus-visible { outline: 3px solid var(--violet); outline-offset: 3px; border-radius: 6px; }
      .wrap { width: min(1200px, 100% - 32px); margin-inline: auto; }
      section[id] { scroll-margin-top: calc(var(--header-h) + 16px); }
      .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

      /* ---------- Type ---------- */
      /* Headings use Fraunces at its sharp, high-contrast end, like a nib under pressure.
         Only the wordmark keeps the soft, wonky cut, to match the snail. */
      h1, h2, .brand span, .footer-mark span, .footer-tagline, .story-steps li::before, .summary .total dd, .price-figure, .panel > h3 {
        font-family: var(--display);
        font-variation-settings: "SOFT" 0, "WONK" 0;
      }
      .brand span, .footer-mark span { font-variation-settings: "SOFT" 100, "WONK" 1; }
      h2 {
        margin: 0;
        font-weight: 500;
        font-size: clamp(38px, 5vw, 66px);
        line-height: 1;
        letter-spacing: -.03em;
      }
      h3 { margin: 0; font-size: 19px; font-weight: 700; line-height: 1.3; letter-spacing: -.01em; }
      /* Set like a page, not a screen: no headline ends on one lonely word, no paragraph on a stub. */
      h1, h2, h3, .faq summary, .sample .said, .proof, .footer-tagline { text-wrap: balance; }
      p, li, dd { text-wrap: pretty; }

      /* ---------- Header ---------- */
      .top { position: fixed; inset: 0 0 auto; z-index: 10; transition: transform .45s var(--ease), background .3s, box-shadow .3s; }
      .top.solid { background: rgba(242, 236, 223, .9); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 1px 0 var(--line); }
      .top.away { transform: translateY(-100%); }
      /* The header spans the full window: logo hard left, links hard right. */
      .top .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: auto; padding-inline: clamp(16px, 3vw, 40px); height: calc(var(--header-h) - var(--banner-h)); }
      .banner { display: flex; margin: 0; align-items: center; justify-content: center; height: var(--banner-h); padding-inline: 16px; background: var(--violet); color: var(--card); font-size: 13px; font-weight: 700; letter-spacing: .02em; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .brand { display: flex; align-items: center; gap: 10px; min-height: 44px; text-decoration: none; }
      .brand svg { width: 40px; height: 40px; flex: none; }
      .brand span { font-size: 26px; font-weight: 800; letter-spacing: -.03em; }
      /* The wordmark bounces along like a snail's trail, and settles when you point at it. */
      .word { white-space: nowrap; }
      .word > span { display: inline-block; transition: transform .35s var(--spring); }
      .word > span:nth-child(odd) { transform: translateY(-.05em) rotate(-6deg); }
      .word > span:nth-child(even) { transform: translateY(.05em) rotate(5deg); }
      .word > span:nth-child(3n) { color: var(--violet); }
      @media (hover: hover) { a:hover > .word > span { transform: none; } }
      .top-end { display: flex; align-items: center; gap: 30px; }
      .top nav { display: flex; align-items: center; gap: 30px; font-weight: 600; font-size: 15px; }
      .top nav a { padding-block: 10px; text-decoration: none; white-space: nowrap; }
      .top nav a:hover { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; }
      /* Search is a quiet magnifier, as on Unopost and unofax. */
      .search-link { display: grid; place-items: center; width: 44px; height: 44px; margin-inline: -8px -14px; color: var(--text-soft); transition: color .3s; }
      .search-link:hover { color: var(--night); }
      .search-link svg { width: 20px; height: 20px; }
      .menu-toggle { display: none; position: relative; width: 44px; height: 44px; margin-right: -8px; padding: 0; border: 0; background: none; color: var(--night); cursor: pointer; }
      .menu-toggle span { position: absolute; left: 11px; width: 22px; height: 2.5px; border-radius: 2px; background: currentColor; transition: transform .3s var(--ease), opacity .2s; }
      .menu-toggle span:nth-child(1) { top: 14px; }
      .menu-toggle span:nth-child(2) { top: 21px; }
      .menu-toggle span:nth-child(3) { top: 28px; }
      .menu-open .menu-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
      .menu-open .menu-toggle span:nth-child(2) { opacity: 0; }
      .menu-open .menu-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

      /* ---------- Buttons ---------- */
      .btn {
        appearance: none;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 48px;
        border: 0;
        border-radius: var(--r-control);
        background: var(--violet);
        color: var(--card);
        font: inherit;
        font-weight: 700;
        font-size: 15px;
        letter-spacing: .005em;
        padding: 12px 24px;
        cursor: pointer;
        text-decoration: none;
        white-space: nowrap;
        box-shadow: var(--shadow-press);
        transition: background .2s, transform .2s var(--ease), box-shadow .2s, translate .6s var(--spring), opacity .4s;
      }
      .btn:hover { background: var(--violet-deep); transform: translateY(-1px); }
      .btn:active { transform: translateY(1px) scale(.98); }
      .btn[disabled] { background: var(--line); color: var(--text-soft); cursor: not-allowed; transform: none; box-shadow: none; }
      .btn.quiet { background: transparent; color: var(--night); box-shadow: inset 0 0 0 2px var(--night); }
      .btn.quiet:hover { background: rgba(26, 31, 58, .06); }
      .btn.butter { background: var(--lettuce); color: var(--night); box-shadow: 0 8px 18px -8px rgba(205, 236, 92, .6); }
      .btn.butter:hover { background: #dbf27e; }
      .btn.small { min-height: 42px; padding: 9px 18px; }
      .text-btn { min-width: 44px; min-height: 44px; font: inherit; font-size: 14px; font-weight: 700; color: var(--violet); background: none; border: 0; padding: 10px 0 10px 10px; cursor: pointer; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }

      /* ---------- The studio's page ---------- */
      /* The studio is the page: its heading is set like the homepage's section headings. */
      h1 { margin: 0; font-weight: 500; font-size: clamp(38px, 5vw, 66px); line-height: 1; letter-spacing: -.03em; }
      /* The snail inches along as it eats the card, and a note above the steps says what became of a link. */
      @keyframes inch { from { scale: 1 1; } to { scale: 1.07 .96; } }
      .resume { display: inline-flex; align-items: center; gap: 4px 14px; flex-wrap: wrap; justify-content: center; margin-bottom: 20px; padding: 10px 16px; background: var(--card); border-radius: 14px; box-shadow: var(--shadow-paper); font-size: 15px; font-weight: 600; }
      .resume[hidden] { display: none; }
      .resume .btn[hidden] { display: none; }

      .field-label { display: block; margin-bottom: 8px; font-size: 13px; font-weight: 700; letter-spacing: .01em; }
      .prompt {
        display: flex;
        align-items: center;
        gap: 8px;
        width: min(640px, 100%);
        margin-inline: auto;
        padding: 7px 7px 7px 24px;
        background: var(--card);
        border-radius: 999px;
        box-shadow: var(--shadow-paper);
        transition: box-shadow .2s;
      }
      .prompt:focus-within { box-shadow: 0 0 0 3px var(--violet), var(--shadow-paper); }
      .prompt .btn { box-shadow: none; }
      .prompt input {
        flex: 1;
        min-width: 0;
        border: 0;
        outline: 0;
        background: none;
        padding: 8px 0;
        font-family: inherit;
        font-weight: 500;
        font-size: clamp(18px, 1.8vw, 21px);
        color: var(--text);
      }
      .prompt input::placeholder { color: rgba(26, 31, 58, .45); }
      .ideas { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; margin-top: 16px; font-size: 14px; font-weight: 600; color: var(--night); }
      .ideas > span { margin-right: 2px; }
      .ideas button {
        flex: none;
        font: inherit;
        color: var(--night);
        background: rgba(255, 253, 248, .7);
        border: 0;
        border-radius: 999px;
        min-height: 40px;
        padding: 8px 16px;
        cursor: pointer;
        transition: background .2s, transform .35s var(--spring);
      }
      @media (hover: hover) { .ideas button:hover { background: var(--card); transform: translateY(-2px); } }

      /* The card handles like a folded card in your hand: it tilts a little as the pointer
         moves over it, the cover swings open on its spine, and it's lifted to be turned over. */
      .preview { perspective: 1600px; }
      .card3d { perspective: 2000px; transform: rotateX(var(--tilt-y, 0deg)) rotateY(var(--tilt-x, 0deg)); transition: transform .6s var(--ease); }
      .card3d.held-tilt { transition-duration: .15s; }
      .card {
        position: relative;
        aspect-ratio: 5 / 7;
        container-type: inline-size;
        transform-style: preserve-3d;
        transition: transform 1s var(--ease);
      }
      /* The cover is a leaf hinged on the left. Opened, it stands out towards you like a card
         stood open on a shelf, and the card slides right so the open card stays centred. */
      .leaf { position: absolute; inset: 0; transform-style: preserve-3d; transform-origin: left center; transition: transform 1.1s var(--ease); }
      /* In 3D the card and leaf are planes of their own in front of the inside page, set back
         a pixel; taps go through them to the faces, so the page can be written on. */
      .card, .leaf { pointer-events: none; }
      .card .face { pointer-events: auto; }
      .card.open { transform: translateX(33%); }
      .card.open .leaf { transform: rotateY(-128deg); }
      /* The inside of the cover: plain card, a shade darker towards the fold. */
      .face.fold { transform: rotateY(180deg); background: var(--grain), linear-gradient(270deg, rgba(26, 31, 58, .1), transparent 14%), var(--card); transition: visibility 0s .5s; }
      .card:not(.open) .face.fold { visibility: hidden; }
      .card.open .face.fold { transition-delay: 0s; }
      .face {
        position: absolute;
        inset: 0;
        border-radius: var(--r-paper);
        overflow: hidden;
        backface-visibility: hidden;
        background: var(--card);
        box-shadow: var(--shadow-lift);
      }
      .face canvas { display: block; width: 100%; height: 100%; }
      .face.inside {
        transform: translateZ(-1px);
        display: flex;
        flex-direction: column;
        padding: 14% 12%;
        font-family: var(--hand);
        color: var(--violet);
        font-size: 7cqi;
        line-height: 1.55;
        /* Ink settles into the fibres a little. */
        text-shadow: 0 0 .6px rgba(43, 59, 209, .55);
        background: var(--grain), linear-gradient(90deg, rgba(26, 31, 58, .06), transparent 7%), var(--card);
      }
      /* The back faces away behind the inside page; turning the card over shows it. Each shows
         only while it's the side asked for, swapping half way through the turn. */
      .card.turned { transform: rotateY(-180deg); }
      .face.back { transform: translateZ(-2px) rotateY(180deg); --ink: var(--violet); --url: #6467b0; }
      .face.back svg { display: block; width: 100%; height: 100%; }
      .back .ink { stroke: var(--ink); }
      .back .dot { fill: var(--ink); stroke: none; }
      .back .fade { stop-color: var(--ink); stop-opacity: 0; }
      .back .full { stop-color: var(--ink); }
      .back .url { fill: var(--url); }
      .back .paper-a, .back .paper-b { stop-color: var(--card); }
      .face.inside, .face.back { transition: visibility 0s .5s; }
      .card.turned .face.inside, .card:not(.turned) .face.back { visibility: hidden; }
      /* The message and sign-off are typed on the page itself, in the pen's hand and ink. */
      .face.inside .msg, .face.inside .sign {
        display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 0 .15em;
        font: inherit; line-height: inherit; color: inherit; text-shadow: inherit;
        background: transparent; border: 0; border-radius: 4px; outline: 0; resize: none;
        -webkit-user-select: text; user-select: text; transition: background-color .2s;
      }
      .face.inside .msg { flex: 1; min-height: 0; white-space: pre-wrap; overflow-wrap: anywhere; overflow: hidden; }
      .face.inside .sign { flex: none; margin-top: .3em; text-align: right; }
      .face.inside :is(.msg, .sign)::placeholder { color: #a8a493; opacity: 1; text-shadow: none; }
      .face.inside :is(.msg, .sign)[readonly] { cursor: inherit; }
      .face.inside .sign[readonly]::placeholder { color: transparent; }
      .order[data-step="1"] .face.inside :is(.msg, .sign) { cursor: text; }
      .order[data-step="1"] .face.inside :is(.msg, .sign):is(:hover, :focus) { background-color: rgba(43, 59, 209, .05); }
      .order[data-step="1"] .face.inside :is(.msg, .sign):focus-visible { box-shadow: 0 0 0 1.5px rgba(43, 59, 209, .35); }
      /* A hand-drawn signature sits under the sign-off at the size the pen writes it: 60mm of the card's 148.5. */
      .face.inside .sig { display: none; position: relative; flex: none; width: 40.4cqi; aspect-ratio: 10 / 3; margin: .15em 0 0 auto; padding: 0; border: 0; border-radius: 4px; background: transparent; color: inherit; font: inherit; cursor: inherit; transition: background-color .2s; }
      .face.inside .sig.signed, .order[data-step="1"] .face.inside .sig { display: block; }
      .order[data-step="1"] .face.inside .sig { cursor: pointer; }
      .order[data-step="1"] .face.inside .sig:not(.signed) { border-bottom: 1.5px dashed #c9c4b2; border-radius: 4px 4px 0 0; }
      .order[data-step="1"] .face.inside .sig:is(:hover, :focus-visible) { background-color: rgba(43, 59, 209, .05); outline: 0; }
      .face.inside .sig svg { display: block; width: 100%; height: 100%; overflow: visible; }
      .sig-hint { position: absolute; inset: 0; display: grid; place-items: end center; padding-bottom: .1em; font-size: .6em; line-height: 1; color: #a8a493; text-shadow: none; }
      .sig.signed .sig-hint { display: none; }
      .sig path, .sig-pad path, .pc-sig path { fill: none; stroke: var(--violet); stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }
      .pc-sig { display: block; width: 40%; aspect-ratio: 10 / 3; margin: 2px 0 0 auto; }
      .sig-pad { width: min(640px, calc(100vw - 32px)); max-width: none; box-sizing: border-box; padding: 24px; border: 0; border-radius: var(--r-panel); background: var(--grain), var(--paper); color: var(--text); box-shadow: var(--shadow-lift); }
      .sig-pad::backdrop { background: rgba(26, 31, 58, .5); }
      .sig-pad h3 { margin: 0 0 4px; }
      .sig-pad .hint { margin: 0; }
      .sig-board { margin-top: 16px; border-radius: var(--r-paper); background: var(--grain), var(--card); box-shadow: var(--shadow-paper); }
      .sig-board svg { display: block; width: 100%; aspect-ratio: 10 / 3; touch-action: none; cursor: crosshair; -webkit-user-select: none; user-select: none; }
      .sig-board .rule { stroke: var(--line); stroke-width: 2; stroke-dasharray: 10 8; }
      .sig-pad path { stroke-width: 6; }
      .sig-pad .actions { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
      .sig-pad .actions .text-btn { margin-right: auto; padding-left: 0; }
      .card.open.inking .msg { animation: ink-in 1s var(--ease) both; }
      @keyframes ink-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

      /* ---------- Order ---------- */
      .order { position: relative; min-height: 100svh; box-sizing: border-box; padding-block: var(--section-y); padding-inline: clamp(16px, 3vw, 40px); }
      .head-actions { display: flex; gap: 0 22px; flex-wrap: wrap; }
      .clear-card, .save-link-btn { padding: 10px 0; }
      .clear-card[hidden], .save-link-btn[hidden] { display: none; }
      /* "Email me a link": the card in progress, to pick up on another device. */
      .save-link { width: min(520px, calc(100vw - 32px)); max-width: none; box-sizing: border-box; padding: 0; border: 0; border-radius: var(--r-panel); background: var(--grain), var(--paper); color: var(--text); box-shadow: var(--shadow-lift); }
      .save-link form { padding: 24px; }
      .save-link::backdrop { background: rgba(26, 31, 58, .5); }
      .save-link h3 { margin: 0 0 12px; }
      .save-link .actions { display: flex; justify-content: flex-end; margin-top: 12px; }
      .save-link .save-row { display: flex; gap: 12px; align-items: end; flex-wrap: wrap; }
      .save-link input { flex: 1 1 200px; min-width: 0; font: inherit; color: var(--text); background: transparent; border: 0; border-bottom: 1.5px solid var(--rule); border-radius: 0; padding: 10px 0; }
      .save-link input:focus { outline: 0; border-bottom-color: var(--violet); box-shadow: 0 1.5px 0 var(--violet); }
      .clear-card.armed { color: #c2306a; }
      /* Starting fresh: the snail crawls across the studio (under the header, so the menu stays) and eats the card, leaving
         a wet streak, then the page underneath fades back in empty. */
      .munch { position: absolute; inset: 0 -40px; z-index: 9; pointer-events: none; }
      .munch[hidden] { display: none; }
      .munch::before { content: ""; position: absolute; inset: 0 auto 0 0; width: calc(var(--eaten, 0) * 100%); background: var(--paper); }
      .munch::after { content: ""; position: absolute; left: 0; top: var(--snail-y, 50%); width: calc(var(--eaten, 0) * 100%); height: 6px; border-radius: 3px; background: linear-gradient(90deg, rgba(221, 227, 250, 0), rgba(221, 227, 250, .9)); }
      .munch .mascot { position: absolute; left: calc(var(--eaten, 0) * 100%); top: var(--snail-y, 50%); width: clamp(64px, 7vw, 96px); translate: -70% calc(-100% + 8px); }
      .munch .mascot svg { display: block; width: 100%; height: auto; transform-origin: 10% 100%; animation: inch .35s ease-in-out infinite alternate; }
      .munch.done { opacity: 0; transition: opacity .5s var(--ease); }
      /* The steps sit at the top left, over the title; Email me a link and Start fresh keep to the title's right. */
      .order-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 14px 24px; margin-bottom: clamp(28px, 4vw, 48px); }
      .order-head > .steps { grid-row: 1; grid-column: 1 / -1; justify-self: start; }
      .order-head > h1 { grid-row: 2; grid-column: 1; }
      .order-head > .head-actions { grid-row: 2; grid-column: 2; }
      .steps { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px; counter-reset: step; }
      .steps li { counter-increment: step; }
      .steps button {
        display: flex;
        align-items: center;
        gap: 8px;
        min-height: 44px;
        font: inherit;
        font-size: 14px;
        font-weight: 600;
        color: var(--text-soft);
        background: none;
        border: 0;
        border-radius: 999px;
        padding: 7px 14px 7px 7px;
        cursor: pointer;
      }
      .steps button::before {
        content: counter(step);
        display: grid;
        place-items: center;
        width: 28px;
        height: 28px;
        border-radius: 50%;
        box-shadow: inset 0 0 0 1.5px var(--rule);
        font-size: 13px;
        font-weight: 700;
      }
      .steps button:disabled { opacity: .55; cursor: default; }
      .steps button[aria-current="step"] { color: var(--night); background: var(--card); box-shadow: var(--shadow-paper); }
      .steps button[aria-current="step"]::before { background: var(--violet); color: var(--card); box-shadow: none; }
      .steps button.done::before { content: "✓"; background: var(--lettuce); color: var(--night); box-shadow: none; }

      .order-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(32px, 6vw, 96px); align-items: start; }
      .preview {
        position: sticky;
        top: calc(var(--header-h) + 16px);
        display: grid;
        justify-items: center;
        gap: 14px;
        padding: clamp(32px, 4.5vw, 56px);
        background: var(--grain), var(--lettuce);
        border-radius: var(--r-panel);
      }
      .preview .card3d { width: min(300px, 78%); }
      /* Laptop screens are wide but short: the card is sized by the height too, so the whole
         sticky preview, with its button and note, stays on screen beside the steps. */
      @media (min-width: 1024px) {
        .preview .card3d { width: min(360px, 84%, (100svh - var(--header-h) - 320px) * 5 / 7); }
        /* Choosing a cover fits on one screen, and the googly eyes offer under the card takes some of
           that height, so the note gives its room back. --eyes-room is everything on screen but the card. */
        .order { --eyes-room: 518px; }
        /* While choosing, the chosen card is half as big again as would fit, in a wider column, and the page grows to hold it. */
        .order { --card-w: min(540px, 32vw, (100svh - var(--header-h) - var(--eyes-room)) * 15 / 14); }
        .order[data-step="0"] .order-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
        .order[data-step="0"] .preview .card3d { width: var(--card-w); }
        .order[data-step="0"] .preview:has(.eyes:not([hidden])) .preview-note { display: none; }
        /* The green stays one size on the cover step, whether it holds a chosen card with its buttons and
           googly eyes under it, a photo being framed, or nothing yet: as tall as a chosen card makes it.
           --panel-extra is the panel's height less the card's. */
        .order { --panel-extra: 322px; }
        .order[data-step="0"] .preview { align-content: start; min-height: calc(var(--card-w) * 7 / 5 + var(--panel-extra)); box-sizing: border-box; }
      }
      @media (min-width: 1024px) and (max-height: 920px) {
        .order { padding-top: 40px; }
        .preview { padding: 28px 40px; }
        .order-head { margin-bottom: 24px; }
        .order { --eyes-room: 408px; --panel-extra: 266px; }
      }
      .preview-note { margin: 0; font-size: 13px; font-weight: 500; color: var(--night); text-align: center; }
      .flip {
        min-height: 44px;
        font: inherit;
        font-size: 14px;
        font-weight: 700;
        color: var(--night);
        background: var(--card);
        border: 0;
        border-radius: var(--r-control);
        padding: 10px 18px;
        cursor: pointer;
        box-shadow: 0 2px 6px rgba(26, 31, 58, .12);
      }
      .flip:hover { background: #fff; }
      .flips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
      .preview-close { display: none; place-items: center; position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 12px; width: 44px; height: 44px; border: 0; border-radius: 50%; background: var(--card); color: var(--night); font: inherit; font-size: 26px; line-height: 1; cursor: pointer; box-shadow: 0 2px 6px rgba(26, 31, 58, .12); }
      html.held { overflow: hidden; }

      .panel[hidden] { display: none; }
      .panel:not([hidden]) { animation: panel-in .45s var(--ease); }
      @keyframes panel-in { from { opacity: 0; transform: translateX(12px); } }
      .panel > h3 { font-weight: 500; font-size: 34px; line-height: 1.1; letter-spacing: -.02em; margin-bottom: 8px; }
      .panel > p { margin: 0 0 28px; color: var(--text-soft); max-width: 52ch; }

      .options { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
      .options:empty { display: none; }
      .option {
        padding: 0;
        border: 0;
        background: none;
        aspect-ratio: 5 / 7;
        border-radius: var(--r-paper);
        overflow: hidden;
        cursor: pointer;
        box-shadow: var(--shadow-paper);
        transition: transform .5s var(--spring), box-shadow .3s;
        animation: deal .7s var(--spring) backwards;
      }
      .option:nth-child(2) { animation-delay: .09s; }
      .option:nth-child(3) { animation-delay: .18s; }
      @keyframes deal { from { opacity: 0; transform: translateY(30px) rotate(-3deg); } }
      @media (hover: hover) { .option:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); } }
      .option[aria-pressed="true"] { box-shadow: 0 0 0 3px var(--paper), 0 0 0 6px var(--violet), var(--shadow-paper); }
      .option canvas { display: block; width: 100%; height: 100%; }
      /* Covers can't be dragged out, long-pressed or right-clicked to save. Screenshots can't be stopped,
         but previews are only 600px with a corner mark; the print file never leaves the server. */
      .option, .browse-card, .preview .face, .eye-pad { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
      .option canvas, .browse-card img, .face canvas, .eye-pad canvas { -webkit-user-drag: none; }
      /* Covers still being painted: a soft sheen crosses the blank paper. */
      .option.developing { cursor: progress; background: linear-gradient(110deg, var(--card) 35%, #ece4d2 50%, var(--card) 65%) 0 0 / 300% 100%; animation: deal .7s var(--spring) backwards, develop 1.4s linear infinite; }
      .option.developing canvas { opacity: 0; }
      @keyframes develop { to { background-position: -150% 0; } }
      .options.four { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
      /* A go makes one cover, and it's shown in the preview, so the covers aren't laid out to choose
         from. They stay in the page, hidden, for the states that follow whether there are any. */
      #options { display: none !important; }
      /* The cover still being painted: the sheen crosses the preview's blank paper. */
      .preview.developing .leaf > .face:first-child { cursor: progress; background: linear-gradient(110deg, var(--card) 35%, #ece4d2 50%, var(--card) 65%) 0 0 / 300% 100%; animation: develop 1.4s linear infinite; }
      .preview.developing #preview-canvas { opacity: 0; }
      .options.many { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 12px; }
      .options.many .option, .options.four .option { animation-delay: 0s; }
      .cover-status { margin: 14px 0 0; font-size: 14px; font-weight: 600; color: var(--text-soft); }
      .cover-status[hidden], .notice[hidden], .photo-choice[hidden] { display: none; }
      .turnstile { margin-top: 14px; }
      .turnstile:empty { display: none; }
      .notice { margin-top: 22px; padding: clamp(16px, 3vw, 22px); border-radius: 20px; background: var(--grain), var(--trail); }
      .notice h4 { margin: 0 0 6px; font-family: var(--display); font-size: 24px; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; }
      .notice p { margin: 0; color: var(--text-soft); font-size: 15px; max-width: 56ch; }
      .notice-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
      .notice-actions:empty { display: none; }
      /* Out of goes and not signed in: sign up, with Google, Apple or a code by email. */
      .signup .sso { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
      .signup .sso[hidden], .signup form[hidden], .signup .signup-or[hidden] { display: none; }
      .sso-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; padding: 0 20px; border-radius: 999px; font-size: 15px; font-weight: 700; text-decoration: none; }
      .sso-btn svg { width: 20px; height: 20px; flex: none; }
      .sso-btn.google { background: #fff; color: #1f1f1f; box-shadow: 0 0 0 1.5px #747775; }
      .sso-btn.apple { background: #000; color: #fff; }
      .sso-btn[hidden] { display: none; }
      .signup .signup-or { margin-top: 16px; font-size: 14px; font-weight: 700; color: var(--text-soft); }
      .signup form { display: flex; flex-wrap: wrap; align-items: end; gap: 10px 14px; margin-top: 8px; }
      .signup form label { flex-basis: 100%; font-size: 14px; color: var(--text-soft); }
      .signup form input { flex: 1 1 220px; min-width: 0; font: inherit; color: var(--text); background: transparent; border: 0; border-bottom: 1.5px solid var(--rule); border-radius: 0; padding: 10px 0; }
      .signup form input:focus { outline: 0; border-bottom-color: var(--violet); box-shadow: 0 1.5px 0 var(--violet); }
      .signup form .text-btn { padding-left: 0; }
      .signup .signup-status { margin-top: 10px; font-size: 14px; font-weight: 600; }
      .signup .signup-status:empty { display: none; }
      .signup .signup-status.error { color: var(--error, #b3261e); }
      .signup .signup-terms { margin-top: 12px; font-size: 12px; }
      .signup .signup-terms a { color: inherit; }
      .goes .text-btn { padding: 6px 0 6px 10px; font-size: 14px; }
      .goes .text-btn[hidden] { display: none; }
      .photo-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: none; min-height: 44px; padding: 0 12px; border: 0; border-radius: var(--r-control); background: transparent; color: var(--night); font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; }
      .photo-btn:hover { background: rgba(26, 31, 58, .06); }
      .photo-btn svg { width: 22px; height: 22px; flex: none; }
      .photo-choice { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(200px, 1fr); gap: clamp(20px, 3vw, 32px); align-items: start; margin-top: 22px; padding: clamp(18px, 3.5vw, 30px); border-radius: 20px; background: var(--card); box-shadow: 0 0 0 1.5px var(--line); scroll-margin-top: calc(var(--header-h) + 16px); }
      /* While a photo is being set up, the words-first intro and prompt step aside. */
      .panel:has(.photo-choice:not([hidden])) :is(#cover-intro, .cover-tabs, .again, .browse, .photo-drop, .actions) { display: none; }
      /* The frame is where the photo is framed: dragged to move, pinched, scrolled or slid to zoom. */
      .photo-frame { position: relative; aspect-ratio: 5 / 7; border-radius: var(--r-paper); overflow: hidden; background: var(--line); box-shadow: var(--shadow-paper); touch-action: none; cursor: grab; -webkit-user-select: none; user-select: none; }
      .photo-frame:active { cursor: grabbing; }
      .photo-frame:focus-visible { outline: 3px solid var(--violet); outline-offset: 3px; }
      .photo-frame img { position: absolute; top: 0; left: 0; max-width: none; transform-origin: 0 0; pointer-events: none; }
      /* A thirds grid shows while framing, to line faces up by. */
      .photo-frame::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent calc(33.33% - .5px), rgba(255, 253, 248, .7) 0 calc(33.33% + .5px), transparent 0 calc(66.67% - .5px), rgba(255, 253, 248, .7) 0 calc(66.67% + .5px), transparent 0), linear-gradient(transparent calc(33.33% - .5px), rgba(255, 253, 248, .7) 0 calc(33.33% + .5px), transparent 0 calc(66.67% - .5px), rgba(255, 253, 248, .7) 0 calc(66.67% + .5px), transparent 0); opacity: 0; transition: opacity .2s; pointer-events: none; }
      .photo-frame.moving::after { opacity: 1; }
      /* Zoom: a round button either side of the slider, and Reset, always in its place. */
      .photo-fit { display: grid; grid-template-columns: 28px minmax(0, 1fr) 28px 28px; align-items: center; gap: 8px; min-height: 32px; margin-top: 14px; }
      .fit-btn { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--text-soft); cursor: pointer; transition: background-color .15s, color .15s; }
      .fit-btn svg { width: 16px; height: 16px; }
      @media (hover: hover) { .fit-btn:not(:disabled):hover { background: var(--line); color: var(--violet); } }
      .fit-btn:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
      .fit-btn:disabled { opacity: .35; cursor: default; }
      /* The track fills with violet up to the thumb (--pct, set as it zooms). */
      .photo-fit input { -webkit-appearance: none; appearance: none; width: 100%; min-width: 0; height: 18px; margin: 0; background: transparent; cursor: pointer; }
      .photo-fit input:disabled { opacity: .5; cursor: default; }
      .photo-fit input::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: linear-gradient(var(--violet), var(--violet)) 0 0 / var(--pct, 0%) 100% no-repeat, var(--line); }
      .photo-fit input::-moz-range-track { height: 6px; border-radius: 3px; background: linear-gradient(var(--violet), var(--violet)) 0 0 / var(--pct, 0%) 100% no-repeat, var(--line); }
      .photo-fit input::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; margin-top: -6px; border: 0; border-radius: 50%; background: var(--violet); box-shadow: 0 0 0 3px #fff, 0 2px 6px rgba(26, 31, 58, .3); }
      .photo-fit input::-moz-range-thumb { width: 18px; height: 18px; border: 0; border-radius: 50%; background: var(--violet); box-shadow: 0 0 0 3px #fff, 0 2px 6px rgba(26, 31, 58, .3); }
      .photo-fit input:focus-visible { outline: 0; }
      .photo-fit input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--violet); }
      .photo-fit input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--violet); }
      .photo-sharp { display: inline-flex; align-items: center; gap: 8px; margin: 16px 0 0; padding: 6px 14px 6px 12px; border-radius: 999px; background: #e3f1e6; font-size: 13px; font-weight: 600; color: var(--night); }
      .photo-sharp::before { content: ""; width: 8px; height: 8px; flex: none; border-radius: 50%; background: #3f9b5a; }
      .photo-sharp.soft { background: #fbecd6; }
      .photo-sharp.soft::before { background: #d8902f; }
      .photo-sharp:empty { display: none; }
      /* BYO cover: a big target to tap, or to drop a photo on. */
      .photo-drop { margin-top: 16px; }
      .photo-drop[hidden] { display: none; }
      .drop-zone { display: grid; justify-items: center; gap: 6px; width: 100%; padding: clamp(26px, 5vw, 40px) 20px; border: 2px dashed var(--line); border-radius: 22px; background: var(--grain), var(--card); font: inherit; color: var(--night); text-align: center; cursor: pointer; transition: border-color .2s, background-color .2s, transform .35s var(--spring); }
      .drop-zone svg { width: 40px; height: 40px; color: var(--violet); }
      .drop-zone strong { font-size: 18px; }
      .drop-zone .hint { margin: 0; font-size: 14px; }
      @media (hover: hover) { .drop-zone:hover { border-color: var(--violet); } }
      .drop-zone:focus-visible { outline: 0; border-color: var(--violet); box-shadow: 0 0 0 3px rgba(43, 59, 209, .2); }
      .panel.dropping .drop-zone { border-color: var(--violet); background-color: var(--trail); transform: scale(1.01); }
      .photo-drop > .hint { margin: 12px 0 0; font-size: 13px; }
      /* AI on or off, under the ways to choose. */
      [data-ai="off"] .needs-ai { display: none; }
      .photo-side h4 { margin: 0 0 10px; font-size: clamp(20px, 2.4vw, 24px); }
      .photo-side .hint { margin: 0; max-width: 52ch; font-size: 15px; line-height: 1.55; }
      .photo-side #photo-note:empty { display: none; }
      .photo-side #photo-note { margin-top: 10px; }
      .consent { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start; margin: 0 0 18px; font-size: 14px; font-weight: 600; cursor: pointer; }
      .consent input { width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--violet); cursor: pointer; }
      /* The address book's people, offered as their name is typed, and saving a new one below the address. */
      .suggestions.people li { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
      .suggestions.people small { flex: none; font-size: 13px; color: var(--text-soft); }
      .suggestions.people .people-head { padding: 4px 14px 6px; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); cursor: default; }
      @media (hover: hover) { .suggestions.people .people-head:hover { background: none; } }
      .fields .book-save { grid-column: 1 / -1; margin: 0; }
      .fields .book-save[hidden] { display: none; }
      .fields .book-save input { width: 20px; padding: 0; border: 0; box-shadow: none; }
      /* A friend's code, tucked under the summary until it's wanted. */
      .referral { margin: 4px 0 14px; }
      .referral > .text-btn { padding-left: 0; }
      .referral-form { max-width: 400px; margin-top: 6px; }
      .referral-form[hidden] { display: none; }
      .referral-form label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 700; }
      .referral-field { display: flex; align-items: center; gap: 8px; padding: 5px 5px 5px 20px; border-radius: var(--r-control); background: var(--card); box-shadow: 0 0 0 1.5px var(--line); transition: box-shadow .2s; }
      .referral-field:focus-within { box-shadow: 0 0 0 2px var(--violet); }
      .referral-field input { flex: 1; min-width: 0; padding: 8px 0; border: 0; background: none; font: inherit; font-size: 17px; font-weight: 700; color: var(--text); text-transform: uppercase; letter-spacing: .16em; }
      .referral-field input:focus { outline: 0; }
      .referral-field input::placeholder { font-size: 15px; font-weight: 400; letter-spacing: 0; text-transform: none; color: rgba(26, 31, 58, .35); }
      .referral-field .btn { min-height: 42px; margin: 0; padding: 8px 20px; font-size: 14px; }
      .referral .hint { margin: 8px 0 0; font-size: 14px; }
      .referral .hint:empty { display: none; }
      .referral .hint.error { color: var(--error, #b3261e); }
      /* A code that's on: a little ticket with its tick, what it takes off, and a way to take it back. */
      .referral .hint.applied { display: flex; align-items: center; gap: 10px; max-width: 400px; margin: 0; padding: 10px 6px 10px 12px; border-radius: 14px; background: var(--trail); color: var(--night); }
      .referral .applied .mark { display: grid; place-items: center; flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--lettuce); font-size: 12px; font-weight: 800; }
      .referral .applied span:not(.mark) { flex: 1; }
      .referral .applied .text-btn { flex: none; min-height: 0; padding: 4px 8px; font-size: 13px; }
      /* The photo's own button and Edit this cover, each as wide as its words, side by side. */
      .photo-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
      .photo-actions .btn { min-height: clamp(48px, 3.6vw, 56px); padding-inline: clamp(22px, 2.2vw, 34px); font-size: clamp(15px, 1.1vw, 17px); }
      .photo-actions #edit-cover { margin: 0; }
      /* Googly eyes go on photos too: ticked here, under the photo as they are under the card,
         they're circled on the cover once it's kept. */
      .photo-eyes { margin-top: 14px; padding: 12px 16px; border-radius: 20px; background: var(--grain), var(--trail); }
      .photo-eyes[hidden] { display: none; }
      .photo-side .photo-rights { margin: 14px 0 0; max-width: 60ch; font-size: 12.5px; line-height: 1.5; }
      /* Starting a card: that the studio uses AI, and the terms that come with it. */
      .ai-terms { margin: 6px 0 0; font-size: 12px; }
      .ai-terms a { color: inherit; }
      /* A photo of their own, chosen or being framed, has its own terms in place of the AI ones. */
      .panel:is(:has(#tab-photo[aria-selected="true"]), :has(.photo-choice:not([hidden]))) .ai-terms:not(.byo-terms),
      .panel:not(:has(#tab-photo[aria-selected="true"])):not(:has(.photo-choice:not([hidden]))) .byo-terms { display: none; }
      /* Browse says what it is in its own words and uses no AI, so the Design intro and AI terms step aside. */
      .panel:has(#tab-browse[aria-selected="true"]) :is(#cover-intro, .ai-terms) { display: none; }
      .photo-side .text-btn { padding-left: 0; }
      /* Change photo, and Design from scratch while AI covers are on, side by side under the button. */
      .photo-other { display: flex; flex-wrap: wrap; column-gap: 28px; margin-top: 22px; padding-top: 10px; border-top: 1.5px solid var(--line); }
      /* While a photo is framed its own button goes on, so the step's one is put away. */
      .photo-choice:not([hidden]) ~ .actions { display: none; }
      .order:has(.photo-choice.busy) :is(.photo-go, .photo-frame, .photo-fit, .photo-other) { opacity: .5; pointer-events: none; }
      /* On a computer the photo's frame, zoom and googly eyes stand in the preview in place of the card. */
      .order:has(.photo-choice:not([hidden])) .preview { grid-template-columns: minmax(0, 1fr); }
      .order:has(.photo-choice:not([hidden])) .preview { scroll-margin-top: calc(var(--header-h) + 16px); }
      /* Photo, zoom and googly eyes share one width, the photo's, so they read as one unit. The photo is
         the size the card would be, so the panel is the same size whichever way the cover is made. */
      .preview > .photo-tools { --frame-w: min(100%, var(--card-w, min(300px, 78%))); display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; width: var(--frame-w); container-type: inline-size; }
      .preview > .photo-tools > :is(.photo-frame, .photo-fit, .photo-eyes) { width: 100%; box-sizing: border-box; }
      /* Edit this cover sits half on the photo, half off it. */
      .preview > .photo-tools #edit-cover { max-width: 60%; min-height: 36px; margin-top: -18px; padding: 0 16px 0 12px; gap: 6px; font-size: 13.5px; box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--violet), 0 6px 14px -6px rgba(31, 44, 158, .6); }
      .preview > .photo-tools #edit-cover svg { width: 14px; height: 14px; }
      .order .preview > .photo-tools #edit-cover:not(:has(.edit-count:not([hidden]))) { padding-right: 16px; }
      .order .preview > .photo-tools #edit-cover:hover { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--violet-deep), 0 10px 18px -6px rgba(31, 44, 158, .7); }
      .preview > .photo-tools .photo-eyes { grid-template-columns: 22px minmax(0, 1fr) 40px; column-gap: 10px; margin-top: 14px; padding: 10px 12px; border-radius: 14px; background: var(--grain), var(--card); }
      .preview > .photo-tools .eyes-name { font-size: 14px; line-height: 1.2; text-wrap: balance; }
      .preview > .photo-tools .eyes-name > span:first-child { display: block; }
      .preview > .photo-tools .free { display: inline-block; margin-top: 4px; padding: 2px 7px; font-size: 10.5px; }
      /* Tickbox, name and eyes share the first row, centred on each other; the hint runs under the name to the edge. */
      .preview > .photo-tools .eyes-art { grid-row: 1; align-self: center; width: 40px; margin-left: 0; }
      .preview > .photo-tools .photo-eyes .hint { grid-column: 2 / -1; margin-top: 6px; line-height: 1.45; }
      @container (max-width: 359px) { .photo-eyes .hint { display: none; } }
      @container (max-width: 270px) { .photo-eyes .eyes-art { display: none; } }
      .order:not(:has(.photo-choice:not([hidden]))) .preview > .photo-tools,
      .order:has(.photo-choice:not([hidden])) .preview > :not(.photo-tools) { display: none; }
      .photo-choice:has(> .photo-side:only-child) { grid-template-columns: minmax(0, 1fr); max-width: 640px; padding: clamp(24px, 3vw, 40px); }

      /* The print check on the review step. */
      .print-check { display: grid; grid-template-columns: auto 1fr; gap: 20px; align-items: start; margin-bottom: 26px; padding: clamp(16px, 3vw, 22px); border-radius: 20px; background: var(--grain), var(--trail); }
      .pc-sides { display: flex; gap: 8px; }
      .pc-sides canvas, .pc-inside { display: block; width: 88px; aspect-ratio: 5 / 7; height: auto; border-radius: 3px; box-shadow: var(--shadow-paper); }
      .pc-inside { box-sizing: border-box; padding: 9px 8px; overflow: hidden; background: var(--card); font-family: var(--hand); font-size: 7.5px; line-height: 1.35; color: var(--violet); overflow-wrap: anywhere; }
      .print-check h4 { margin: 0 0 10px; font-size: 17px; }
      .checks { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; font-size: 14px; }
      .checks li { display: grid; grid-template-columns: 22px 1fr; gap: 8px; align-items: start; }
      .checks .mark { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--lettuce); font-size: 12px; font-weight: 800; }
      .checks .warn .mark { background: var(--shell); }
      .checks .text-btn { min-height: 0; padding: 0 0 0 6px; font-size: 13px; }

      /* The cover editor, over the page but under the menu, which stays put while editing. */
      html.editing { overflow: hidden; }
      html.editing .top { z-index: 101; transform: none; background: var(--paper); box-shadow: 0 1px 0 var(--line); }
      .editor { position: fixed; inset: var(--header-h) 0 0; z-index: 100; display: flex; flex-direction: column; background: var(--paper); color: var(--night); }
      .editor[hidden] { display: none; }
      .ed-top { display: flex; align-items: center; gap: 12px; padding: 10px 16px; background: var(--card); box-shadow: 0 1px 0 var(--line); }
      .ed-title { margin: 0 auto 0 0; font-family: var(--display); font-size: 21px; font-weight: 800; letter-spacing: -.02em; }
      .ed-history, .ed-group { display: flex; gap: 2px; }
      .ed-icon { display: inline-grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 12px; background: none; color: var(--night); cursor: pointer; }
      .ed-icon svg { width: 22px; height: 22px; }
      .ed-icon:hover:not(:disabled) { background: var(--trail); }
      .ed-icon:disabled { opacity: .3; cursor: default; }
      .ed-icon[aria-pressed="true"] { background: var(--night); color: var(--card); }
      .ed-icon.danger { color: var(--error); }
      .ed-sides { display: flex; padding: 3px; border-radius: 999px; background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--line); }
      .ed-sides button { min-height: 36px; padding: 0 14px; border: 0; border-radius: 999px; background: none; font: inherit; font-size: 14px; font-weight: 700; color: var(--night); cursor: pointer; }
      .ed-sides button[aria-pressed="true"] { background: var(--night); color: var(--card); }
      .ed-body { position: relative; flex: 1; min-height: 0; display: grid; grid-template-columns: 88px 290px minmax(0, 1fr); }
      .ed-rail { display: flex; flex-direction: column; gap: 4px; padding: 12px 8px; background: var(--card); box-shadow: 1px 0 0 var(--line); }
      .ed-rail button { display: grid; justify-items: center; gap: 4px; padding: 10px 4px; border: 0; border-radius: 14px; background: none; font: inherit; font-size: 12px; font-weight: 700; color: var(--text-soft); cursor: pointer; }
      .ed-rail button svg { width: 24px; height: 24px; }
      .ed-rail button[aria-selected="true"] { background: var(--lettuce); color: var(--night); }
      .ed-panel { overflow-y: auto; padding: 18px; background: var(--card); box-shadow: 1px 0 0 var(--line); }
      .ed-panel h3 { margin-bottom: 12px; }
      .ed-panel section[hidden] { display: none; }
      .ed-panel .hint { margin: 0 0 12px; font-size: 14px; }
      .ed-add { display: block; width: 100%; margin-bottom: 8px; padding: 14px 16px; border: 0; border-radius: 14px; background: var(--paper); color: var(--night); text-align: left; cursor: pointer; }
      .ed-add:hover { background: var(--trail); }
      .ed-add.heading { font: 800 24px "SG Fraunces Bold", var(--display); letter-spacing: -.02em; }
      .ed-add.small { font: 700 15px var(--sans); }
      .ed-add.hand { font: 22px var(--hand); }
      .ed-text-edit { margin-top: 18px; }
      .ed-text-edit[hidden] { display: none; }
      .ed-text-edit label { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 700; }
      .ed-text-edit textarea { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 0; border-radius: 12px; background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--line); color: var(--night); font: inherit; font-size: 16px; resize: vertical; }
      .ed-text-edit textarea:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--violet); }
      .ed-text-edit .hint { margin: 6px 0 0; font-size: 12px; }
      .ed-stickers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
      .sticker { aspect-ratio: 1; padding: 10px; border: 0; border-radius: 14px; background: var(--paper); cursor: pointer; }
      .sticker:hover { background: var(--trail); }
      .sticker svg { display: block; width: 100%; height: 100%; }
      .ed-layers { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
      .ed-layers li { display: flex; align-items: center; gap: 4px; }
      .ed-layers .empty { color: var(--text-soft); font-size: 14px; }
      .layer-name { flex: 1; min-width: 0; min-height: 40px; padding: 0 12px; border: 0; border-radius: 12px; background: var(--paper); color: var(--night); font: inherit; font-size: 14px; font-weight: 600; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
      .layer-name[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--violet); }
      .ed-stage { position: relative; min-width: 0; min-height: 0; display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px; background: var(--grain), var(--paper); }
      .ed-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 10px; max-width: 100%; min-height: 40px; padding: 6px 10px; border-radius: 18px; background: var(--card); box-shadow: var(--shadow-paper); }
      .ed-bar[hidden] { display: flex; visibility: hidden; }
      .ed-font select { min-height: 36px; padding: 0 10px; border: 0; border-radius: 10px; background: var(--paper); color: var(--night); font: inherit; font-size: 14px; font-weight: 600; }
      .ed-size input { width: 110px; accent-color: var(--violet); }
      .ed-colours { display: flex; flex-wrap: wrap; gap: 4px; }
      .swatch { width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: var(--c); box-shadow: inset 0 0 0 1.5px rgba(26, 31, 58, .25); cursor: pointer; }
      .swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--violet); }
      .ed-group[hidden], .ed-font[hidden], .ed-colours[hidden] { display: none; }
      .ed-desk { flex: 1; min-height: 0; width: 100%; display: grid; place-items: center; overflow: hidden; }
      /* editor.js sizes the card to fit the desk. */
      .ed-card, .ed-inside-view { position: relative; border-radius: var(--r-paper); box-shadow: var(--shadow-lift); }
      .ed-card { touch-action: none; user-select: none; -webkit-user-select: none; }
      .ed-card[hidden], .ed-inside-view[hidden] { display: none; }
      .ed-card canvas { display: block; width: 100%; height: 100%; border-radius: inherit; }
      .ed-guides { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
      .ed-guides .safe { fill: none; stroke: #fffdf8; stroke-width: 1.5; stroke-dasharray: 4 5; filter: drop-shadow(0 0 1px rgba(26, 31, 58, .8)); }
      .ed-guides .snap { stroke: var(--postmark); stroke-width: 1.5; }
      .ed-guides .box { fill: none; stroke: var(--violet); stroke-width: 2; }
      .ed-guides .warn { fill: none; stroke: var(--postmark); stroke-width: 2; stroke-dasharray: 6 4; }
      .ed-guides .stem { stroke: var(--violet); stroke-width: 2; }
      .ed-guides .handle { fill: var(--card); stroke: var(--violet); stroke-width: 3; pointer-events: all; cursor: grab; }
      .ed-inside-view { display: flex; flex-direction: column; box-sizing: border-box; padding: 12% 10%; background: var(--card); font-family: var(--hand); color: var(--violet); }
      .ed-inside-msg, .ed-inside-sign { margin: 0; font-size: clamp(15px, 2.4vh, 24px); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
      .ed-inside-sign { margin-top: 1em; }
      .ed-inside-note { margin: auto 0 0; font-family: var(--sans); font-size: 13px; color: var(--text-soft); }
      .ed-hint { margin: 0; font-size: 13px; color: var(--text-soft); text-align: center; }
      .editor.inside .ed-rail, .editor.inside .ed-panel, .editor.inside .ed-history, .editor.inside .ed-hint { opacity: .35; pointer-events: none; }
      @media (max-width: 900px) {
        .ed-top { gap: 8px; padding: 8px 12px; }
        .ed-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
        .ed-history { margin-right: auto; }
        .ed-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
        .ed-stage { grid-row: 1; padding: 10px 12px; }
        .ed-rail { grid-row: 2; flex-direction: row; justify-content: space-around; padding: 6px 8px calc(6px + env(safe-area-inset-bottom)); box-shadow: 0 -1px 0 var(--line); }
        .ed-rail button { flex: 1; padding: 6px 2px; }
        .ed-rail button[aria-selected="true"] { background: none; color: var(--text-soft); }
        .editor.sheet-open .ed-rail button[aria-selected="true"] { background: var(--lettuce); color: var(--night); }
        .ed-panel { position: absolute; left: 0; right: 0; bottom: calc(68px + env(safe-area-inset-bottom)); z-index: 2; max-height: 46%; border-radius: 22px 22px 0 0; box-shadow: 0 -14px 30px -16px rgba(26, 31, 58, .5); transform: translateY(120%); visibility: hidden; transition: transform .3s var(--ease), visibility 0s .3s; }
        .editor.sheet-open .ed-panel { transform: none; visibility: visible; transition: transform .3s var(--ease); }
        .ed-size input { width: 84px; }
        .ed-bar { flex-wrap: nowrap; justify-content: flex-start; width: 100%; box-sizing: border-box; overflow-x: auto; }
        .ed-bar > * { flex: none; }
        .ed-bar[hidden] { display: none; }
        .ed-hint { display: none; }
        .photo-choice { grid-template-columns: minmax(0, 1fr); }
        .photo-frame, .photo-fit, .photo-eyes { width: min(360px, 100%); margin-inline: auto; }
        .photo-actions { flex-direction: column; gap: 10px; margin-top: 18px; }
        .print-check { grid-template-columns: minmax(0, 1fr); }
      }
      /* The three ways to a cover, side by side as cards: what each is, and a line on what it means. */
      .cover-tabs { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 10px; margin-top: 20px; }
      .cover-tabs button { display: grid; justify-items: start; align-content: start; gap: 2px; min-height: 44px; padding: 12px 14px 14px; border: 0; border-radius: 16px; background: var(--card); box-shadow: 0 0 0 1.5px var(--line); font: inherit; color: var(--night); text-align: left; cursor: pointer; }
      .cover-tabs button[hidden] { display: none; }
      /* With AI covers off, Design with AI stays in sight, greyed and tagged Coming soon. */
      .cover-tabs .soon { display: none; justify-self: start; padding: 2px 8px; border-radius: 999px; background: var(--night); color: var(--card); font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
      [data-ai="off"] .cover-tabs .soon { display: inline-block; }
      .cover-tabs button:disabled { cursor: not-allowed; }
      .cover-tabs button:disabled :is(svg, .tab-name, .tab-text) { opacity: .45; }
      .panel > .cover-tabs { margin-bottom: 18px; }
      .cover-tabs svg { width: 24px; height: 24px; margin-bottom: 6px; color: var(--violet); }
      .cover-tabs .tab-name { font-size: 15px; font-weight: 700; line-height: 1.25; }
      .cover-tabs .tab-text { font-size: 13px; font-weight: 500; line-height: 1.3; color: var(--text-soft); }
      .cover-tabs button[aria-selected="true"] { background: var(--lettuce); box-shadow: 0 0 0 2px var(--night); }
      .cover-tabs button[aria-selected="true"] svg, .cover-tabs button[aria-selected="true"] .tab-text { color: var(--night); }
      .cover-tabs button:focus-visible { outline: 3px solid var(--violet); outline-offset: 3px; }
      @media (max-width: 560px) {
        .cover-tabs { gap: 8px; }
        .cover-tabs button { padding: 10px 10px 12px; border-radius: 14px; }
        .cover-tabs svg { width: 22px; height: 22px; margin-bottom: 4px; }
        .cover-tabs .tab-name { font-size: 14px; }
        .cover-tabs .tab-text { font-size: 12px; }
      }
      /* On a computer the three ways to a cover sit on the title's line, over the step's column, as compact
         tabs: an icon and a name each, what each means still read out. Email me a link and Start fresh move up
         to the steps' line to make room. Only the cover step has them, and not while a photo is framed. */
      @media (min-width: 901px) {
        .order-head { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(32px, 6vw, 96px); }
        .order-head > .steps { grid-column: 1; }
        .order-head > .head-actions { grid-row: 1; grid-column: 2; justify-self: end; align-self: center; }
        .order-head > .cover-tabs { grid-row: 2; grid-column: 2; align-self: end; display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 6px; }
        .order-head .cover-tabs button { display: inline-flex; align-items: center; gap: 7px; min-height: 42px; padding: 0 14px 0 11px; border-radius: 999px; white-space: nowrap; }
        .order-head .cover-tabs svg { width: 19px; height: 19px; margin: 0; }
        .order-head .cover-tabs .tab-name { font-size: 14px; }
        .order-head .cover-tabs .tab-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
        @media (hover: hover) { .order-head .cover-tabs button[aria-selected="false"]:hover { transform: none; } }
        .order:not([data-step="0"]) .order-head > .cover-tabs, .order:has(.photo-choice:not([hidden])) .order-head > .cover-tabs { display: none; }
      }
      @media (min-width: 1024px) {
        .order[data-step="0"] .order-head { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
      }
      .again { margin-top: 26px; }
      /* Goes left today, a dot a go, where goes are limited (not on a local preview or dev). */
      .goes { margin-top: 14px; text-align: center; }
      .goes[hidden] { display: none; }
      .goes-count { display: inline-flex; align-items: center; gap: 10px; margin: 0; padding: 7px 16px 7px 12px; border-radius: 999px; background: var(--card); box-shadow: 0 0 0 1.5px var(--line); font-size: 15px; font-weight: 700; color: var(--night); }
      .goes-dots { display: inline-flex; gap: 5px; }
      .goes-dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--lettuce-deep); transition: background-color .3s, box-shadow .3s; }
      .goes-dots i.used { background: transparent; box-shadow: inset 0 0 0 1.5px rgba(26, 31, 58, .28); }
      .goes.out .goes-count { color: var(--text-soft); }
      .again .beta-note { margin: 10px auto 0; max-width: 52ch; font-size: 15px; text-align: center; }
      /* The tip is for writing the sentence: with a cover made, only the count stays. */
      .options:not(:empty) ~ .again:not(.asking) .beta-note { display: none; }
      .again[hidden], .browse[hidden] { display: none; }
      .browse { margin-top: 16px; }
      .browse > .hint { margin: 0 0 12px; }
      .browse-search { box-sizing: border-box; width: 100%; min-height: 44px; margin-bottom: 12px; padding: 8px 16px; border: 0; border-radius: 999px; background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--line); font: inherit; font-size: 16px; color: var(--night); }
      .browse-search:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--violet); }
      .browse-status { margin: -4px 0 12px; }
      .browse-status:empty { display: none; }
      .browse-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
      .browse-filters button { min-height: 36px; padding: 0 14px; border: 0; border-radius: 999px; background: var(--trail); font: inherit; font-size: 14px; font-weight: 600; color: var(--night); cursor: pointer; }
      .browse-filters button[aria-pressed="true"] { background: var(--night); color: var(--card); }
      .browse-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 16px 10px; }
      .browse-card { display: block; padding: 0; border: 0; background: none; font: inherit; font-size: 13px; font-weight: 700; line-height: 1.3; color: var(--night); text-align: left; cursor: pointer; }
      .browse-card[hidden] { display: none; }
      .browse-card img { display: block; width: 100%; height: auto; aspect-ratio: 5 / 7; margin-bottom: 8px; object-fit: cover; border-radius: var(--r-paper); box-shadow: var(--shadow-paper); transition: transform .5s var(--spring), box-shadow .3s; }
      @media (hover: hover) { .browse-card:hover img { transform: translateY(-4px); box-shadow: var(--shadow-lift); } }
      .browse-card[aria-pressed="true"] img { box-shadow: 0 0 0 3px var(--paper), 0 0 0 6px var(--violet), var(--shadow-paper); }
      /* The cover box is a big chat box: room to describe the cover, the buttons in a bar beneath. */
      .again .prompt { flex-direction: column; align-items: stretch; width: 100%; margin: 0; padding: 18px 18px 10px 22px; border-radius: 26px; box-shadow: 0 0 0 1.5px var(--line); }
      .again .prompt textarea { min-height: 4.35em; padding: 4px 0; border: 0; outline: 0; background: none; resize: none; font-family: inherit; font-weight: 500; font-size: clamp(19px, 1.9vw, 23px); line-height: 1.45; color: var(--text); }
      .again .prompt textarea::placeholder { color: rgba(26, 31, 58, .45); }
      .prompt-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
      .again .prompt:focus-within { box-shadow: 0 0 0 3px var(--violet); }
      .again .ideas { justify-content: flex-start; }
      .again .ideas[hidden] { display: none; }
      .again .ideas button { background: var(--trail); }
      /* With covers made, the box shrinks to one line for another go, so the covers keep the room. */
      .panel:has(.option) .again .prompt { flex-direction: row; align-items: center; padding: 6px 6px 6px 22px; border-radius: 999px; }
      .panel:has(.option) .again .prompt textarea { flex: 1; min-width: 0; min-height: 0; height: 1.45em; padding: 0; font-size: 18px; white-space: nowrap; overflow: hidden; }
      .panel:has(.option) .prompt-bar { flex-wrap: nowrap; }
      .panel:has(.option) .photo-btn { padding: 0 10px; }
      /* The questions are for the first go: the box is only its buttons, under them. Once there are
         covers it's one line again, holding the sentence, until Edit prompt asks them again. Sibling selectors,
         not :has, as a tall box under :has crashed Chrome's headless shell on reload. */
      .options:empty ~ .again .prompt.guided { padding: 12px 0 0; background: none; box-shadow: none; }
      .options:not(:empty) ~ .again:not(.asking) .guide { display: none; }
      /* The sentence can't be typed in: a tap on it asks the questions again, as Edit prompt does. */
      .again .prompt.guided > textarea { cursor: pointer; }
      .options:not(:empty) ~ .again:not(.asking) .prompt.guided > textarea { display: block !important; }
      .options:not(:empty) ~ .again:not(.asking) .prompt.guided > .prompt-bar { justify-content: space-between; }
      .options:not(:empty) ~ .again:not(.asking) .prompt.guided > .prompt-bar .photo-btn { display: inline-flex; }
      /* Edit prompt asks the questions again, answers and all, under the covers (by id, to outrank the one-line box). */
      #again-pane.asking .prompt.guided { flex-direction: column; align-items: stretch; padding: 12px 0 0; background: none; box-shadow: none; border-radius: 0; }
      #again-pane.asking .prompt.guided > .prompt-bar { flex-wrap: wrap; }
      /* No rush: the goes left show at the last question, not before. The one-line box keeps its button. */
      .options:empty ~ .again form.guide-early ~ .goes, .again.asking form.guide-early ~ .goes { display: none; }
      .options:not(:empty) ~ .again:not(.asking) form.guide-early .prompt.guided > .prompt-bar [type=submit] { display: inline-flex; }
      .panel:has(.option) .photo-btn span, .panel:has(.option) .again .field-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
      /* The chosen cover wears a tick. */
      .option, .browse-card { position: relative; }
      .option[aria-pressed="true"]::after, .browse-card[aria-pressed="true"]::after {
        content: "";
        position: absolute;
        top: 8px;
        right: 8px;
        width: 26px;
        height: 26px;
        border-radius: 50%;
        background: var(--violet) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.5l4 4 8-9' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 16px no-repeat;
        box-shadow: 0 0 0 2px var(--card), 0 4px 10px rgba(26, 31, 58, .25);
        animation: boing .5s var(--spring);
      }
      .cover-tabs button { transition: background .25s var(--ease), box-shadow .25s var(--ease), transform .35s var(--spring); }
      @media (hover: hover) { .cover-tabs button[aria-selected="false"]:hover { box-shadow: 0 0 0 1.5px var(--violet); transform: translateY(-2px); } }

      /* On a computer, choosing a cover fits on one screen: the covers take whatever height is left,
         the cards to browse scroll in their own window, and the next step stays in sight above Help.
         Anything that needs more room (a photo, a notice, circling eyes, the questions, before or beside covers) lets the page grow again. */
      @media (min-width: 1024px) and (min-height: 700px) {
        .order[data-step="0"]:not(:has(.photo-choice:not([hidden]), .notice:not([hidden]), .eye-draw:not([hidden]), .resume:not([hidden]), .again.asking:not([hidden]), .options:empty ~ :where(.again:not([hidden])))) {
          display: flex;
          flex-direction: column;
          /* At least a screen tall, and as tall as the green panel needs: the step beside it takes the
             panel's height (contain: size keeps its own content from setting the row's), so the footer
             always starts below the panel and the covers to browse scroll within it. */
          min-height: 100svh;
          padding-bottom: 28px;
          & .order-grid { flex: 1; min-height: 0; align-items: stretch; }
          & .order-grid > .preview { align-self: start; }
          & .order-grid > div:last-child { display: flex; flex-direction: column; min-height: 0; contain: size; }
          & [data-panel="0"] { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
          & [data-panel="0"] > * { flex: none; }
          & .panel > h3 { margin-top: 0; }
          & .panel > p { max-width: none; margin-bottom: 18px; }
          & .panel > p:first-of-type { min-height: 1.6em; }
          & .options:not(.many):not(:empty) { flex: 1 1 0; min-height: 110px; display: flex; gap: 16px; align-items: flex-start; container-type: size; }
          /* The covers to choose from stay smaller than the chosen one beside them: at most four fifths of it. */
          --choice-w: min(200px, (100svh - var(--header-h) - var(--eyes-room)) * 4 / 7);
          & .options:not(.many) .option { flex: none; width: min(var(--choice-w), (100cqw - 32px) / 3, 100cqh * 5 / 7 - 4px); height: auto; }
          & .options.four .option { width: min(var(--choice-w), (100cqw - 48px) / 4, 100cqh * 5 / 7 - 4px); }
          & .options.many:not(:empty) { flex: 1 1 0; min-height: 110px; overflow-y: auto; padding: 6px; margin: -6px; }
          & .again, & .browse { margin-top: 18px; }
          & .browse:not([hidden]) { flex: 2 1 0; min-height: 200px; display: flex; flex-direction: column; }
          & .browse > * { flex: none; }
          & .browse > .hint { margin-bottom: 10px; font-size: 14px; }
          /* The occasions fit on one line beside the card rather than leaving one alone on a second. */
          & .browse-filters { gap: 6px; margin-bottom: 4px; }
          & .browse-filters button { min-height: 34px; padding-inline: 11px; font-size: 13.5px; }
          & .browse-grid {
            flex: 1 1 0;
            min-height: 0;
            overflow-y: auto;
            overscroll-behavior: contain;
            margin-inline: -8px;
            padding: 14px 8px 24px;
            grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
            mask-image: linear-gradient(to bottom, transparent, #000 14px, #000 calc(100% - 32px), transparent);
            scrollbar-width: thin;
            scrollbar-color: var(--line) transparent;
          }
          & .eyes { margin-top: 16px; padding: 14px 18px; }
          /* Write the message sits just under the prompt, not down at the panel's foot. With Browse
             open it's pushed down to where Help floats, so there the buttons stop short of it. */
          & .actions { flex-wrap: nowrap; margin-top: 24px; }
          & .browse:not([hidden]) ~ .actions { padding-right: 116px; }
          & .actions .btn.quiet { min-height: 44px; padding-inline: 18px; font-size: 15px; white-space: nowrap; }
        }
      }
      /* On a laptop screen, fitting on one screen left the cards to browse a strip too short to
         see more than a row in. There the cards run down the page instead, beside the sticky
         preview, and once a card is picked, Write the message keeps to the foot of the screen. */
      @media (min-width: 1024px) and (min-height: 700px) and (max-height: 920px) {
        /* As specific as the one-screen rule above, so it wins. */
        .order[data-step="0"]:has(.browse:not([hidden])) {
          display: block;
          height: auto;
          & [data-panel="0"] { flex: none; }
          & .order-grid > div:last-child { contain: none; }
          & .browse:not([hidden]) { display: block; flex: none; min-height: 0; }
          & .browse-grid { overflow: visible; mask-image: none; padding-bottom: 8px; }
          & .browse:not([hidden]) ~ .actions:has(#cover-next:not(:disabled)) {
            position: sticky;
            bottom: 0;
            z-index: 1;
            margin-top: 8px;
            padding-block: 14px 18px;
            background: rgba(242, 236, 223, .9);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            box-shadow: 0 -1px 0 var(--line);
            animation: bar-up .35s var(--ease);
          }
        }
        @keyframes bar-up { from { opacity: 0; translate: 0 100%; } }
      }
      /* Short laptop screens: the googly eyes offer says less, so the covers get the room. */
      @media (min-width: 1024px) and (max-height: 820px) {
        .order[data-step="0"] .eyes-toggle .hint { display: none; }
        .order[data-step="0"] .panel > h3 { font-size: 30px; }
        .order[data-step="0"] .panel > p { font-size: 16px; }
        .order[data-step="0"] .browse:not([hidden]) { min-height: 160px; }
        .order[data-step="0"] .eyes { padding: 10px 16px; }
        .order { --eyes-room: 360px; --panel-extra: 248px; }
        /* Circling eyes makes the preview taller than the screen, so it scrolls with the page. */
        .order[data-step="0"] .preview:has(.eye-draw:not([hidden])) { position: static; }
        .order[data-step="0"] .preview:has(.eye-draw:not([hidden])) .card3d { width: min(300px, 78%); }
        .order[data-step="0"] .panel:not(:has(.option)) .again .prompt textarea { min-height: 0; height: 2.9em; }
        .order[data-step="0"] .order-head { margin-bottom: 16px; }
      }

      /* Googly eyes: circled on a big copy of the cover, stuck on by hand after printing. */
      .eye-marks { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
      .eye-marks .eye { animation: boing .6s var(--spring) backwards; transform-box: fill-box; transform-origin: center; }
      @keyframes boing { from { transform: scale(.2); } }
      .eye-marks .stroke { fill: none; stroke: var(--card); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 2 10; filter: drop-shadow(0 0 2px rgba(26, 31, 58, .8)); }
      .eyes { margin-top: 26px; padding: clamp(16px, 3vw, 24px); background: var(--grain), var(--trail); border-radius: 20px; }
      .eyes[hidden], .eye-draw[hidden] { display: none; }
      .eyes-toggle { display: grid; grid-template-columns: auto 1fr; column-gap: 12px; align-items: center; margin: 0; cursor: pointer; }
      .eyes-toggle input { width: 22px; height: 22px; margin: 0; accent-color: var(--violet); cursor: pointer; }
      .eyes-name { font-size: 15px; font-weight: 700; }
      .eyes-toggle .hint { grid-column: 2; font-size: 13px; }
      /* A pair of googly eyes beside the offer; the pupils roll about when it's ticked. */
      .eyes-art { grid-column: 3; grid-row: 1 / span 2; width: 58px; height: auto; margin-left: 4px; overflow: visible; }
      .eyes-art .white { fill: #fffdf8; stroke: var(--night); stroke-width: 2.5; }
      .eyes-art .pupil { fill: var(--night); }
      .eyes-art .shine { fill: #fffdf8; }
      .eyes-art .roll { transform-box: view-box; }
      .eyes-art .roll:first-of-type { transform-origin: 17px 21px; }
      .eyes-art .roll:last-of-type { transform-origin: 45px 19px; }
      .eyes-toggle:has(input:checked) .eyes-art .roll { animation: googly 1.1s var(--spring) both; }
      .eyes-toggle:has(input:checked) .eyes-art .roll:last-of-type { animation-name: googly-back; }
      @keyframes googly { 0% { rotate: 0deg; } 35% { rotate: 260deg; } 70% { rotate: 170deg; } 100% { rotate: 200deg; } }
      @keyframes googly-back { 0% { rotate: 0deg; } 35% { rotate: -230deg; } 70% { rotate: -130deg; } 100% { rotate: -160deg; } }
      @media (hover: hover) { .eyes-toggle:hover .eyes-art { animation: wobble .5s var(--ease); } }
      @keyframes wobble { 30% { rotate: -6deg; } 65% { rotate: 4deg; } }
      @media (prefers-reduced-motion: reduce) { .eyes-art, .eyes-art .roll { animation: none !important; } }
      /* On a computer the offer sits under the card it goes on. */
      .preview .eyes { justify-self: stretch; margin-top: 4px; padding: 12px 16px; background: var(--grain), var(--card); }
      .preview .eyes .eye-draw { margin-top: 8px; }
      /* Once ticked, how to circle them says more than what they are. */
      .preview .eyes:has(#eyes-on:checked) .eyes-toggle .hint { display: none; }
      .order:not([data-step="0"]) .preview .eyes { display: none; }
      .free { padding: 2px 8px; border-radius: 999px; background: var(--lettuce); color: var(--night); font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
      .eye-draw { display: grid; grid-template-columns: minmax(0, 240px) 1fr; gap: 18px; align-items: start; margin-top: 16px; animation: panel-in .45s var(--ease); }
      .eye-pad { position: relative; aspect-ratio: 5 / 7; border-radius: var(--r-paper); overflow: hidden; box-shadow: var(--shadow-paper); cursor: crosshair; touch-action: none; user-select: none; -webkit-user-select: none; }
      .eye-pad canvas { display: block; width: 100%; height: 100%; }
      /* On a computer the eyes are circled on the card in the preview, so there's no second copy. */
      .preview.drawing .leaf > .face:first-child { cursor: crosshair; touch-action: none; user-select: none; -webkit-user-select: none; }
      .eye-how.card-side { display: none; }
      @media (min-width: 901px) {
        .eye-draw { grid-template-columns: 1fr; }
        .eye-pad, .eye-how:not(.card-side) { display: none; }
        .eye-how.card-side { display: block; }
      }
      .eye-side .hint { margin: 0; font-size: 13px; }
      .eyes-count { margin: 10px 0 0; font-size: 14px; font-weight: 700; }
      .eye-side .text-btn { padding-left: 0; }
      .eye-side .text-btn:disabled { visibility: hidden; }

      .fields { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 22px 18px; }
      .fields > div { grid-column: span 6; }
      .fields .half { grid-column: span 3; }
      .fields .third { grid-column: span 2; }
      label { display: block; font-size: 13px; font-weight: 700; letter-spacing: .01em; margin-bottom: 4px; }
      .hint { font-weight: 400; color: var(--text-soft); }
      p.hint { font-size: 13px; margin: 6px 0 0; }
      .fields .group-head { margin-top: 18px; }
      .group-head h4 { margin: 0; font-size: 17px; }
      .group-head p { margin: 4px 0 0; }
      .fields input, .fields select, .fields textarea {
        width: 100%;
        font: inherit;
        color: var(--text);
        background: transparent;
        border: 0;
        border-bottom: 1.5px solid var(--rule);
        border-radius: 0;
        padding: 10px 0;
        transition: border-color .2s;
      }
      .fields input:focus, .fields select:focus, .fields textarea:focus { outline: 0; border-bottom-color: var(--violet); box-shadow: 0 1.5px 0 var(--violet); }
      .fields input:disabled { opacity: .45; cursor: not-allowed; }
      .fields input::placeholder, .fields textarea::placeholder { color: rgba(26, 31, 58, .45); }
      /* The message is written on ruled lines, like the card it's going on. */
      .fields textarea { min-height: 150px; resize: none; overflow: hidden; line-height: 1.6; background: repeating-linear-gradient(transparent 0 calc(1.6em - 1px), var(--line) calc(1.6em - 1px) 1.6em) 0 10px / 100% calc(100% - 20px) no-repeat; }
      .count { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--text-soft); margin-top: 6px; }
      .on-card-how { margin: 0; padding: 12px 16px; border-radius: var(--r-paper); background: var(--grain), var(--card); font-weight: 600; }
      .count .too-long { color: var(--error); font-weight: 700; }
      /* How big the pen writes: three pills, like the editor's side switch. */
      .sizes { grid-column: span 6; margin: 0; padding: 0; border: 0; min-width: 0; }
      .sizes legend { padding: 0; margin-bottom: 8px; font-size: 13px; font-weight: 700; letter-spacing: .01em; }
      .size-options { display: inline-flex; padding: 3px; border-radius: 999px; background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--line); }
      .size-options label { position: relative; display: grid; place-items: center; min-width: 44px; min-height: 40px; margin: 0; padding: 0 16px; border-radius: 999px; font-family: var(--hand); font-weight: 400; color: var(--violet); line-height: 1; cursor: pointer; transition: background .2s, color .2s; }
      .size-options input { position: absolute; width: 1px; height: 1px; padding: 0; opacity: 0; pointer-events: none; }
      .size-options label:has(input:checked) { background: var(--night); color: var(--card); }
      .size-options label:has(input:focus-visible) { outline: 3px solid var(--shell); outline-offset: 2px; }
      /* Addresses found as the street is typed, dropped down over the fields below. */
      .finder { position: relative; }
      .suggestions { position: absolute; z-index: 5; left: 0; right: 0; margin: 4px 0 0; padding: 6px 0; list-style: none; background: var(--card); border-radius: var(--r-paper); box-shadow: var(--shadow-lift); }
      .suggestions li { padding: 10px 14px; cursor: pointer; line-height: 1.35; }
      .suggestions li[aria-selected="true"] { background: var(--trail); }
      @media (hover: hover) { .suggestions li:hover { background: var(--trail); } }
      .suggestions li.manual { color: var(--violet); font-weight: 600; }
      .suggestions li.manual:not(:first-child) { margin-top: 6px; border-top: 1px solid var(--line); }
      /* The address is found in one field and shown as a line; its parts come out only to be typed in. */
      #address-form:not([data-address="search"]) .address-search,
      #address-form:not([data-address="found"]) .address-found,
      #address-form:not([data-address="manual"]) .address-part { display: none; }
      .address-found .label { display: block; font-size: 13px; font-weight: 700; letter-spacing: .01em; margin-bottom: 4px; }
      #address-line { margin: 0; padding: 10px 0; border-bottom: 1.5px solid var(--rule); white-space: pre-line; }
      .address-switch { min-width: 0; min-height: 0; padding: 8px 0 0; font-size: 13px; }
      .error { color: var(--error); font-size: 13px; font-weight: 600; margin-top: 6px; }
      .error:empty { display: none; }
      [aria-invalid="true"] { border-bottom-color: var(--error) !important; }

      .actions { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 36px; }
      .actions .btn:only-child, #cover-next { margin-left: auto; }
      #share-covers[hidden], #edit-cover[hidden] { display: none; }
      #edit-cover { gap: 8px; }
      /* On a phone, by the photo's own button while one is framed. */
      .photo-side #edit-cover svg { width: 18px; height: 18px; }
      #edit-cover svg { width: 18px; height: 18px; flex: none; }
      /* How many words, stickers and photos are on the cover so far. */
      .edit-count[hidden] { display: none; }
      .edit-count > [aria-hidden] { display: grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; box-sizing: border-box; border-radius: 11px; background: var(--lettuce); color: var(--night); font-size: 12px; font-weight: 700; line-height: 1; }
      /* Beside the covers it hangs off the bottom edge of the chosen card, so it's plain which card
         it edits. It steps aside while the card is open or turned over: it only edits the front. */
      .preview #edit-cover {
        position: relative;
        z-index: 3;
        margin-top: -44px;
        min-height: 58px;
        padding: 12px 16px 12px 22px;
        gap: 10px;
        background: var(--violet);
        color: var(--card);
        font-size: 17px;
        box-shadow: 0 0 0 3px var(--card), 0 0 0 6px var(--violet), 0 16px 30px -8px rgba(31, 44, 158, .7);
        animation: edit-in .5s var(--spring) backwards;
        transition: background .2s, transform .2s var(--ease), box-shadow .2s, opacity .3s var(--ease), visibility 0s, translate .3s var(--ease);
      }
      .preview #edit-cover:not(:has(.edit-count:not([hidden]))) { padding-right: 26px; }
      .preview #edit-cover svg { width: 21px; height: 21px; }
      .preview #edit-cover:hover { background: var(--violet-deep); transform: translateY(-2px); box-shadow: 0 0 0 3px var(--card), 0 0 0 6px var(--violet-deep), 0 20px 34px -8px rgba(31, 44, 158, .75); }
      /* A ring ripples out from it a few times when a cover is chosen, so it's seen. */
      .preview #edit-cover::after { content: ""; position: absolute; inset: -6px; border-radius: inherit; box-shadow: 0 0 0 0 rgba(43, 59, 209, .55); pointer-events: none; }
      .preview #edit-cover.ping::after { animation: edit-ping 1.6s .6s var(--ease) 3; }
      @keyframes edit-ping { to { box-shadow: 0 0 0 16px rgba(43, 59, 209, 0); } }
      .preview #edit-cover:hover svg { rotate: -12deg; }
      .preview #edit-cover svg { transition: rotate .3s var(--spring); }
      .preview #edit-cover:focus-visible { outline: 3px solid var(--night); outline-offset: 4px; }
      .preview:has(.card.open, .card.turned) #edit-cover { opacity: 0; visibility: hidden; translate: 0 8px; transition: opacity .2s, visibility 0s .2s, translate .2s; }
      .order:not([data-step="0"]) .preview #edit-cover { display: none; }
      @keyframes edit-in { from { opacity: 0; translate: 0 10px; scale: .9; } }
      @media (prefers-reduced-motion: reduce) { .preview #edit-cover, .preview #edit-cover::after { animation: none; } }

      .summary { margin: 0; }
      .summary div { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; padding: 14px 0; border-bottom: 1px solid var(--line); }
      .summary dt { color: var(--text-soft); flex: none; }
      .summary dd { margin: 0; text-align: right; overflow-wrap: anywhere; white-space: pre-line; }
      .review-check { margin: 0 0 8px; padding: 12px 16px; border-radius: var(--r-control); background: var(--card); font-size: 15px; }
      .summary .total { border-bottom: 0; padding-top: 18px; }
      .summary .total dt { color: var(--text); font-weight: 700; }
      .summary .total dd { font-weight: 600; font-size: 36px; line-height: 1; color: var(--violet); }
      .launch-note { margin: 14px 0 0; font-size: 14px; color: var(--text-soft); }
      .pay { margin-top: 22px; }
      .pay h4 { margin: 0 0 10px; font-size: 17px; }
      .secure { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 0; font-size: 13px; color: var(--text-soft); }
      .secure > svg { width: 14px; height: 14px; flex: none; }
      .pay p { margin: 0 0 6px; }

      .done-panel { text-align: center; padding-block: 16px; }
      .done-panel { position: relative; overflow-x: clip; }
      .done-seal.gone { display: none; }
      .done-seal { width: 92px; height: 92px; display: block; margin: 0 auto 18px; filter: drop-shadow(0 8px 12px rgba(26, 31, 58, .3)); }
      .done-panel:not([hidden]) .done-seal { animation: press .9s var(--spring) backwards; }
      @keyframes press { from { opacity: 0; transform: scale(1.8) rotate(-20deg); } }
      .done-panel > p { margin-inline: auto; }
      .done-panel .for { font-family: var(--hand); font-size: 26px; color: var(--violet); margin: 4px 0 8px; }
      .done-panel h3:focus { outline: 0; }
      .done-panel .actions { justify-content: center; }
      .done-panel .btn[hidden], .pay[hidden], .done-panel [hidden] { display: none; }

      /* The paid card's envelope: airmail edge, a perforated snail stamp, and today's postmark thumped on last. */
      .envelope {
        position: relative; display: block; width: min(380px, 100%); aspect-ratio: 1.6; margin: 4px auto 26px;
        border: 9px solid transparent; border-radius: 6px; box-shadow: var(--shadow-lift); rotate: -2deg; text-align: left;
        background: linear-gradient(#ffe3ae, #ffd590) padding-box, repeating-linear-gradient(-45deg, var(--postmark) 0 12px, var(--card) 12px 20px, var(--violet) 20px 32px, var(--card) 32px 40px) border-box;
        animation: env-in .8s var(--spring) backwards;
      }
      @keyframes env-in { from { opacity: 0; translate: 0 60px; rotate: 6deg; } }
      .envelope.thump { animation: env-in .8s var(--spring) backwards, thump .35s .95s ease-out; }
      @keyframes thump { 40% { translate: 0 3px; scale: .985; } }
      .stamp {
        position: absolute; top: 12px; right: 12px; width: 23%; aspect-ratio: 4 / 5; padding: 5px; background: var(--card); rotate: 4deg;
        -webkit-mask: linear-gradient(#000 0 0) content-box, radial-gradient(circle, #0000 2.4px, #000 2.8px) -4px -4px / 8px 8px;
        mask: linear-gradient(#000 0 0) content-box, radial-gradient(circle, #0000 2.4px, #000 2.8px) -4px -4px / 8px 8px;
        filter: drop-shadow(0 1px 1px rgba(26, 31, 58, .25)); animation: stamp-on .5s .55s var(--spring) backwards;
      }
      .stamp > span { display: grid; place-items: center; height: 100%; background: var(--lettuce); outline: 1.5px solid var(--night); outline-offset: -4px; }
      .stamp svg { width: 70%; height: 70%; }
      @keyframes stamp-on { from { opacity: 0; transform: translateY(-30px) rotate(-25deg) scale(1.4); } }
      .postmark { position: absolute; top: 18px; right: 15%; display: flex; align-items: center; color: var(--postmark); opacity: .85; mix-blend-mode: multiply; rotate: -14deg; animation: postmark .45s .95s cubic-bezier(.5, 0, .7, .4) backwards; }
      .pm-ring { order: 2; display: grid; place-content: center; width: 78px; height: 78px; border: 2.5px solid; border-radius: 50%; text-align: center; line-height: 1.15; font-family: var(--sans); }
      .pm-ring small { font-size: 8.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
      .pm-ring b { margin-block: 3px; padding-block: 2px; border-block: 1.5px solid; font-size: 11px; letter-spacing: .04em; }
      .postmark svg { width: 70px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2.5; }
      @keyframes postmark { from { opacity: 0; scale: 2.2; } }
      .env-to { position: absolute; left: 12%; right: 30%; bottom: 34%; font-family: var(--hand); font-size: clamp(24px, 7vw, 34px); color: var(--violet-deep); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-bottom: 1.5px solid rgba(26, 31, 58, .25); animation: ink-in 1s 1.3s steps(14) backwards; }
      .env-where { position: absolute; left: 12%; right: 30%; bottom: 16%; font-family: var(--hand); font-size: clamp(16px, 4.5vw, 21px); color: var(--violet-deep); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-bottom: 1.5px solid rgba(26, 31, 58, .25); min-height: 1.4em; animation: ink-in .8s 2s steps(10) backwards; }

      /* The order reference, as a tear-off ticket: press it to copy. */
      .ref {
        display: inline-grid; grid-template-columns: auto auto; align-items: center; gap: 0 16px; margin: 10px auto 4px; padding: 10px 14px 10px 22px;
        font: inherit; color: var(--night); text-align: left; cursor: copy;
        background: radial-gradient(circle at 0 50%, #0000 7px, var(--card) 7.5px); border: 0; border-radius: 6px; box-shadow: var(--shadow-paper);
        transition: transform .3s var(--spring), box-shadow .2s;
      }
      .ref:hover { transform: translateY(-2px) rotate(-1deg); box-shadow: var(--shadow-lift); }
      .ref small { grid-column: 1; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
      .ref strong { grid-column: 1; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 22px; letter-spacing: .08em; }
      .ref span { grid-column: 2; grid-row: 1 / 3; padding: 6px 12px; border-left: 2px dashed var(--line); font-size: 13px; font-weight: 700; color: var(--violet); }

      /* After paying, the reference tears off the top of a ticket that holds the trail. */
      .tracker { max-width: 600px; margin: 18px auto 10px; background: var(--card); border-radius: 18px; box-shadow: var(--shadow-paper); }
      .tracker .ref { display: grid; grid-template-columns: 1fr auto; width: 100%; margin: 0; padding: 14px 16px 14px 22px; background: none; border-radius: 18px 18px 0 0; box-shadow: none; border-bottom: 2px dashed var(--line); }
      .tracker .ref:hover { transform: none; box-shadow: none; background: var(--paper); }
      .tracker .journey { margin: 56px 12px 20px; }
      .tracker-foot { margin: 0; padding: 12px 20px 14px; border-top: 1px solid var(--line); font-size: 14px; color: var(--text-soft); }
      .tracker-foot:empty { display: none; }
      .tracker-foot a { color: var(--violet); font-weight: 700; }

      /* Where the card is: the snail at the first stop of its trail, the rest dotted out ahead. */
      .journey { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); max-width: 560px; margin: 46px auto 18px; padding: 0; list-style: none; }
      .journey::before { content: ""; position: absolute; top: 6px; left: 10%; right: 10%; height: 4px; background: radial-gradient(circle, var(--rule) 1.8px, #0000 2.3px) 0 50% / 11px 4px repeat-x; }
      .journey::after { content: ""; position: absolute; top: 6px; left: 10%; width: 6%; height: 4px; border-radius: 2px; background: var(--lettuce-deep); }
      .journey li { position: relative; display: grid; justify-items: center; align-content: start; gap: 2px; font-size: 13px; line-height: 1.25; color: var(--text-soft); animation: deal .5s var(--spring) backwards; }
      .journey li::before { content: ""; position: relative; z-index: 1; width: 16px; height: 16px; margin-bottom: 6px; box-sizing: border-box; border: 2.5px solid var(--rule); border-radius: 50%; background: var(--paper); }
      .journey li:nth-child(2) { animation-delay: 1.5s; } .journey li:nth-child(3) { animation-delay: 1.6s; } .journey li:nth-child(4) { animation-delay: 1.7s; } .journey li:nth-child(5) { animation-delay: 1.8s; }
      .journey li.now { color: var(--night); font-weight: 700; animation-delay: 1.4s; }
      .journey li.now::before { background: var(--lettuce); border-color: var(--night); }
      .journey small { font-size: 12px; font-weight: 400; color: var(--text-soft); }
      .journey-snail { position: absolute; bottom: 100%; left: 50%; width: 38px; height: 38px; margin: 0 0 -10px -6px; transform-origin: bottom; animation: crawl 1.2s 1.4s var(--ease) backwards, inch .7s 2.6s ease-in-out infinite alternate; }
      @keyframes crawl { from { translate: -60px 0; opacity: 0; } }

      /* Paper confetti, thrown once when the postmark lands. */
      .confetti { position: absolute; top: 120px; left: 50%; width: 9px; height: 14px; border-radius: 2px; pointer-events: none; animation: fling 1.6s cubic-bezier(.2, .7, .4, 1) forwards; }
      @keyframes fling {
        0% { transform: translate(0, 0) rotate(0); opacity: 1; }
        40% { transform: translate(calc(var(--x) * .7), var(--y)) rotate(calc(var(--r) * .4)); opacity: 1; }
        100% { transform: translate(var(--x), calc(var(--y) + 260px)) rotate(var(--r)); opacity: 0; }
      }

      /* Handwriting: each tile writes the visitor's own words in that hand. */
      .hands { margin: 36px 0 0; padding: 0; border: 0; min-width: 0; }
      .hands legend { padding: 0; font-size: 13px; font-weight: 700; letter-spacing: .01em; }
      .hands > .hint { margin: 2px 0 14px; }
      .hand-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
      .hand-option {
        position: relative;
        display: grid;
        align-content: start;
        gap: 4px;
        min-height: 104px;
        margin: 0;
        padding: 12px 14px;
        background: var(--card);
        border-radius: 16px;
        box-shadow: 0 0 0 1.5px var(--line);
        cursor: pointer;
        transition: box-shadow .2s, transform .4s var(--spring);
      }
      @media (hover: hover) { .hand-option:hover { transform: translateY(-2px); box-shadow: 0 0 0 1.5px var(--rule), var(--shadow-paper); } }
      .hand-option:has(input:checked) { box-shadow: 0 0 0 2.5px var(--violet), var(--shadow-paper); }
      .hand-option:has(input:focus-visible) { outline: 3px solid var(--shell); outline-offset: 3px; }
      .hand-option input { position: absolute; opacity: 0; pointer-events: none; }
      .hand-name { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; }
      .hand-name::before { content: ""; flex: none; width: 16px; height: 16px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--rule); transition: box-shadow .2s; }
      .hand-option:has(input:checked) .hand-name::before { box-shadow: inset 0 0 0 5px var(--violet); }
      .hand-sample { font-size: calc(var(--hand-scale) * 20px); color: var(--violet); line-height: 1.45; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
      .hand-option.own { grid-column: 1 / -1; min-height: 0; grid-template-columns: auto 1fr; align-items: center; column-gap: 12px; background: var(--grain), var(--trail); box-shadow: none; }
      .hand-option.own:has(input:checked) { box-shadow: 0 0 0 2.5px var(--violet); }
      .hand-option.own .hand-name { grid-column: 1 / -1; }
      .hand-option.own .hand-name::before { box-shadow: inset 0 0 0 1.5px var(--night); }
      .hand-option.own:has(input:checked) .hand-name::before { box-shadow: inset 0 0 0 5px var(--violet); }
      .hand-option.own .hint { grid-column: 1 / -1; font-size: 13px; }
      .beta { padding: 2px 8px; border-radius: 999px; background: var(--postmark); color: var(--card); font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }

      .own-hand { margin-top: 14px; padding: clamp(16px, 3vw, 24px); background: var(--card); border-radius: 20px; box-shadow: 0 0 0 1.5px var(--line); animation: panel-in .45s var(--ease); }
      .own-steps { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 14px; counter-reset: own; }
      .own-steps li { counter-increment: own; display: grid; grid-template-columns: 28px 1fr; column-gap: 12px; }
      .own-steps li::before { content: counter(own); grid-row: span 3; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--night); color: var(--card); font-size: 13px; font-weight: 700; }
      .own-steps strong { font-size: 15px; }
      .own-steps .hint { font-size: 13px; }
      .pangram { margin: 10px 0 0; padding: 12px 14px; font-size: 15px; font-weight: 600; line-height: 1.5; background: repeating-linear-gradient(transparent 0 calc(1.5em - 1px), var(--line) calc(1.5em - 1px) 1.5em) 0 12px / 100% calc(100% - 24px) no-repeat, var(--paper); border-radius: 10px; }
      .drop { display: grid; place-items: center; min-height: 148px; margin: 0; padding: 16px; border-radius: 16px; border: 2px dashed var(--rule); background: var(--paper); text-align: center; cursor: pointer; transition: border-color .2s, background .2s; }
      .drop:hover, .drop.over { border-color: var(--violet); background: var(--trail); }
      .drop:has(input:focus-visible) { outline: 3px solid var(--shell); outline-offset: 3px; }
      .drop.filled { padding: 8px; border-style: solid; border-color: var(--line); background: var(--paper); }
      .drop-text { display: grid; justify-items: center; gap: 4px; }
      .drop-text svg { width: 30px; height: 30px; color: var(--violet); margin-bottom: 4px; }
      .drop img { display: block; max-width: 100%; max-height: 240px; border-radius: 10px; }
      .drop img[hidden], .drop-text[hidden] { display: none; }
      .sample-actions { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 4px; font-size: 14px; font-weight: 700; }
      .sample-actions[hidden] { display: none; }
      .sample-ok { display: flex; align-items: center; gap: 8px; }
      .sample-ok::before { content: "✓"; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--lettuce); font-size: 12px; font-weight: 800; }
      .own-note { margin-top: 12px; }

      /* ---------- Footer ---------- */
      footer {
        background: var(--trail-band) top / 100% 10px no-repeat, var(--grain), var(--night);
        color: var(--paper);
        padding-block: clamp(68px, 9vw, 108px) 32px;
        overflow: hidden;
      }
      .footer-mark { display: flex; align-items: center; gap: .14em; font-size: min(17vw, 240px); line-height: .85; text-decoration: none; }
      /* The g's tail dips onto the postcard below, so it sits on top. */
      .footer-mark { --logo-line: #fffdf8; position: relative; z-index: 1; }
      .footer-mark svg { width: .62em; height: .62em; flex: none; }
      .footer-mark .word > span:nth-child(3n) { color: var(--lettuce); }
      .footer-mark span { font-weight: 800; letter-spacing: -.05em; }
      /* The links sit on the back of an airmail postcard, tucked under the wordmark:
         the message on the left, address lines on the right, a snail stamp franked in the corner. */
      .footer-cols {
        position: relative;
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
        gap: 28px clamp(32px, 5vw, 72px);
        padding: clamp(28px, 4vw, 52px);
        border: 10px solid transparent;
        border-image: repeating-linear-gradient(-45deg, var(--postmark) 0 14px, var(--card) 14px 28px, var(--violet) 28px 42px, var(--card) 42px 56px) 10;
        background: var(--grain), var(--card);
        color: var(--night);
        rotate: -1.5deg;
        box-shadow: 0 2px 4px rgba(0, 0, 0, .2), 0 40px 60px -30px rgba(0, 0, 0, .7);
      }
      .footer-cols::before {
        content: ""; position: absolute; top: clamp(18px, 3vw, 34px); right: clamp(18px, 3vw, 34px); width: 84px; height: 102px; rotate: 4deg;
        background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 102'%3E%3Crect width='84' height='102' fill='%23ffb547'/%3E%3Crect x='11' y='11' width='62' height='80' fill='%23fffdf8' stroke='%231a1f3a' stroke-width='1.5'/%3E%3Ctext x='17' y='27' font-family='Georgia,serif' font-size='11' font-weight='700' fill='%231a1f3a'%3EAUS%3C/text%3E%3Ctext x='67' y='84' text-anchor='end' font-family='Georgia,serif' font-size='13' font-weight='700' fill='%23e5482b'%3E1%C2%A2%3C/text%3E%3Cg transform='translate(17 34) scale(.47)'%3E%3Cpath d='M6 84 C6 77 12 75 20 75 L62 75 C70 75 74 69 75 61 L77 44 C78 36 83 32 89 33 C95 34 97 40 96 47 L93 71 C91 84 83 90 70 90 L12 90 C8 90 6 88 6 84 Z' fill='%232b3bd1' stroke='%231a1f3a' stroke-width='5' stroke-linejoin='round'/%3E%3Cpath d='M82 36 L74 15 M91 35 L95 13' stroke='%231a1f3a' stroke-width='5' stroke-linecap='round'/%3E%3Ccircle cx='73' cy='13' r='7' fill='%23fffdf8' stroke='%231a1f3a' stroke-width='4.5'/%3E%3Ccircle cx='74.5' cy='13.5' r='2.6' fill='%231a1f3a'/%3E%3Ccircle cx='95.5' cy='11' r='7' fill='%23fffdf8' stroke='%231a1f3a' stroke-width='4.5'/%3E%3Ccircle cx='97' cy='11.5' r='2.6' fill='%231a1f3a'/%3E%3Ccircle cx='40' cy='47' r='32' fill='%23cdec5c' stroke='%231a1f3a' stroke-width='5'/%3E%3Cpath d='M40 47 a3.5 3.5 0 0 1 7 0 a7 7 0 0 1 -14 0 a10.5 10.5 0 0 1 21 0 a14 14 0 0 1 -28 0 a17.5 17.5 0 0 1 35 0' fill='none' stroke='%232b3bd1' stroke-width='5.5' stroke-linecap='round'/%3E%3C/g%3E%3C/svg%3E") center / 100% 100%;
        /* Perforated edges: bites out of every side. */
        --r: 4px;
        mask: radial-gradient(var(--r), #0000 97%, #000) round calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)), linear-gradient(#000 0 0) no-repeat 50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
      }
      .footer-cols::after {
        content: ""; position: absolute; top: clamp(30px, 4.4vw, 50px); right: clamp(64px, 7vw, 84px); width: 190px; height: 86px; rotate: -9deg; opacity: .5; pointer-events: none;
        background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 90' fill='none' stroke='%231a1f3a' stroke-width='2.5'%3E%3Cpath d='M2 22 q12 -8 24 0 t24 0 t24 0 t24 0 M2 36 q12 -8 24 0 t24 0 t24 0 t24 0 M2 50 q12 -8 24 0 t24 0 t24 0 t24 0 M2 64 q12 -8 24 0 t24 0 t24 0 t24 0'/%3E%3Ccircle cx='150' cy='45' r='38'/%3E%3Ccircle cx='150' cy='45' r='30'/%3E%3Ctext x='150' y='42' text-anchor='middle' font-family='Georgia,serif' font-size='11' font-weight='700' letter-spacing='1.5' fill='%231a1f3a' stroke='none'%3ESLOW%3C/text%3E%3Ctext x='150' y='56' text-anchor='middle' font-family='Georgia,serif' font-size='11' font-weight='700' letter-spacing='1.5' fill='%231a1f3a' stroke='none'%3EINK%3C/text%3E%3C/svg%3E") center / contain no-repeat;
      }
      .footer-note { display: flex; flex-direction: column; }
      .footer-support { margin: auto 0 0; padding-top: 28px; max-width: 34ch; font-size: 15px; line-height: 1.5; }
      .footer-support a { font-weight: 700; color: inherit; }
      .footer-social { display: inline-flex; align-items: center; gap: 6px; }
      .footer-social svg { width: 16px; height: 16px; flex: none; }
      .footer-tagline { max-width: 8ch; font-size: clamp(36px, 5vw, 64px); font-weight: 600; line-height: .98; letter-spacing: -.02em; color: var(--violet); rotate: -3deg; transform-origin: left; }
      /* A snail's dotted trail wanders off after the message. */
      .footer-tagline::after { content: ""; display: block; width: min(300px, 26vw); aspect-ratio: 6; margin-top: 28px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 80'%3E%3Cpath d='M4 40 C80 10 160 70 240 40 S400 10 476 40' fill='none' stroke='%232b3bd1' stroke-width='6' stroke-linecap='round' stroke-dasharray='0 17'/%3E%3C/svg%3E") left / contain no-repeat; }
      .footer-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: end; column-gap: 28px; padding: 132px 0 4px clamp(24px, 4vw, 56px); border-left: 2px solid var(--line); font-size: 15px; font-weight: 700; }
      /* Each link is an address line; pointing at one sweeps a highlighter across it. */
      .footer-links a { display: block; padding: 14px 6px 6px; border-bottom: 1.5px solid var(--rule); color: var(--night); text-decoration: none; background: linear-gradient(var(--lettuce) 0 0) left bottom / 0 100% no-repeat; transition: background-size .35s var(--ease, ease), translate .35s var(--spring, ease); }
      .footer-links a:hover, .footer-links a[aria-current="page"] { background-size: 100% 100%; translate: 4px 0; }
      @media (max-width: 720px) {
        .footer-cols { grid-template-columns: 1fr; margin-top: 8px; padding: 24px 20px; rotate: -1deg; }
        .footer-cols::before { width: 63px; height: 76px; --r: 3px; }
        .footer-cols::after { top: 20px; right: 64px; width: 128px; height: 58px; }
        /* Stamp and postmark get the top row to themselves, like a real postcard. */
        .footer-tagline { max-width: 6.5ch; padding-top: 72px; font-size: 40px; }
        .footer-tagline::after { width: 180px; margin-top: 16px; }
        .footer-links { grid-template-columns: 1fr; padding: 0; border-left: 0; }
      }
      .footer-small { display: flex; justify-content: space-between; align-items: center; gap: 12px 32px; flex-wrap: wrap; margin-top: clamp(40px, 6vw, 64px); padding-top: 20px; border-top: 1px solid rgba(242, 236, 223, .16); font-size: 14px; color: #a9aec4; }
      .footer-country { max-width: 72ch; margin: 20px 0 0; font-size: 13px; line-height: 1.6; color: #a9aec4; }
      .footer-secure { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
      .footer-secure > svg { width: 14px; height: 14px; flex: none; }
      .payment-icons { display: inline-flex; gap: 4px; margin-left: 4px; }
      .payment-icon { height: 24px; width: auto; }
      .lang { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 14px; font-weight: 600; }
      .lang[hidden] { display: none; }
      /* 16px keeps iOS from zooming in when it's tapped. */
      .lang select { font: inherit; font-size: 16px; color: var(--night); background: var(--paper); border: 0; border-radius: var(--r-control); padding: 6px 12px; }

      /* It opens straight onto the steps, just below the fixed header. */
      .order { padding-top: calc(var(--header-h) + clamp(24px, 4vw, 56px)); }
      @media (min-width: 1024px) and (max-height: 920px) {
        .order { padding-top: calc(var(--header-h) + 24px); }
      }

      /* ---------- Responsive ---------- */
      @media (max-width: 900px) {
        .order-grid { display: flex; flex-direction: column; gap: 20px; }
        .order-grid > div:last-child { width: 100%; min-width: 0; }
        /* On phones the preview becomes a compact strip pinned above the form while you write. */
        .preview { order: -1; top: calc(var(--header-h) + 8px); z-index: 4; background: var(--grain), var(--lettuce); display: flex; align-items: center; justify-content: flex-start; gap: 14px; padding: 10px 14px; border-radius: 20px; box-shadow: 0 10px 24px -16px rgba(26, 31, 58, .5); }
        .preview .card3d { width: 56px; flex: none; }
        /* Opened, the cover stands out to the left of the little card: make room for it. */
        .preview:not(.big) .card3d { transition: transform .6s var(--ease), margin .9s var(--ease); }
        .preview:not(.big):has(.card.open) .card3d { margin-left: 26px; }
        .preview-note { text-align: left; flex: 1; }
        .order[data-step="0"] .preview:not(.filled), .order[data-step="4"] .preview { display: none; }
        /* Choosing a cover, the one made shows above the questions, as big as at review. */
        .order[data-step="0"] .preview.filled:not(.big) { position: static; align-self: stretch; flex-direction: column; padding: 20px 14px; }
        .order[data-step="0"] .preview.filled:not(.big) .card3d { width: min(200px, 52vw); }
        .order[data-step="0"] .preview.filled:not(.big) .preview-note { flex: none; text-align: center; }
        .order[data-step="2"] .preview, .order[data-step="3"] .preview { position: static; }
        /* At review the whole card is shown big enough to read, not as a thumbnail. */
        .order[data-step="3"] .preview:not(.big) { flex-direction: column; padding: 20px 14px; }
        .order[data-step="3"] .preview:not(.big) .card3d { width: min(240px, 62vw); }
        .order[data-step="3"] .preview:not(.big) .preview-note { flex: none; text-align: center; }
        .preview .card3d { cursor: zoom-in; }
        /* While writing, the inside page lies flat, full width, to write on: the cover stays shut out of the way. */
        .order[data-step="1"] .preview:not(.big) { position: static; flex-direction: column; padding: 16px 14px; }
        .order[data-step="1"] .preview:not(.big) .card3d { width: min(320px, 78vw); margin-left: 0; cursor: auto; }
        .order[data-step="1"] .preview:not(.big) .card.open { transform: none; }
        .order[data-step="1"] .preview:not(.big) .leaf { display: none; }
        .order[data-step="1"] .preview:not(.big) .preview-note { flex: none; text-align: center; }
        /* Tapping the little card, or asking to see a side, opens it full size over the page. */
        .order .preview.big {
          position: fixed; inset: 0; z-index: 30; flex-direction: column; justify-content: center; gap: 18px;
          padding: calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom));
          border-radius: 0; box-shadow: none; animation: big-in .25s ease-out;
        }
        .preview.big .card3d { width: min(82vw, (100svh - 230px) * 5 / 7); cursor: auto; animation: big-card .45s var(--spring); }
        /* Open, the card is half again as wide with its cover standing out, so it's held a little smaller. */
        .preview.big .card3d { transition: width .9s var(--ease); }
        .preview.big:has(.card.open) .card3d { width: min(54vw, (100svh - 230px) * 5 / 7); }
        .preview.big .preview-note { flex: none; text-align: center; }
        .preview.big .preview-close { display: grid; }
        @keyframes big-in { from { opacity: 0; } }
        @keyframes big-card { from { transform: scale(.6); } }
      }
      /* Phones and narrow tablets: the section links fold into a hamburger; the order button stays in view. */
      @media (max-width: 900px) {
        .top-end { gap: 12px; }
        .menu-toggle { display: block; }
        .top nav { display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0; padding: 8px 16px 16px; background: var(--paper); box-shadow: 0 1px 0 var(--line), 0 18px 30px -20px rgba(26, 31, 58, .45); font-size: 17px; }
        .top.menu-open { background: var(--paper); box-shadow: 0 1px 0 var(--line); }
        .top.menu-open nav { display: flex; }
        .top nav a { padding-block: 14px; border-bottom: 1px solid var(--line); }
        .top nav a:last-child { border-bottom: 0; }
      }
      @media (max-width: 640px) {
        :root { --header-h: calc(68px + var(--banner-h)); }
        /* Phones: a blurred fixed header is costly to repaint while scrolling, so use a near-solid one. */
        .top.solid { background: rgba(242, 236, 223, .98); backdrop-filter: none; -webkit-backdrop-filter: none; }
        .brand span { font-size: 23px; }
        .prompt { flex-direction: column; align-items: stretch; border-radius: 26px; padding: 8px; }
        .prompt input { padding: 10px 14px; }
        .again .prompt { padding: 14px 12px 8px 16px; }
        .prompt-bar .btn { flex: 1; }
        .steps { gap: 2px; }
        .steps button { font-size: 0; gap: 0; padding: 8px; min-width: 44px; justify-content: center; }
        .steps button[aria-current="step"] { font-size: 13px; padding: 8px 12px 8px 8px; gap: 8px; }
        .steps button::before { font-size: 12px; }
        .options { gap: 10px; }
        .eye-draw { grid-template-columns: 1fr; }
        .eye-pad { width: min(100%, 320px); margin-inline: auto; }
        .panel > h3 { font-size: 28px; }
        .hand-options { gap: 10px; }
        .hand-option { min-height: 96px; padding: 10px 12px; }
        .hand-sample { font-size: calc(var(--hand-scale) * 17px); }
        .fields .half, .fields .third { grid-column: span 6; }
        .fields .pair { grid-column: span 3; }
        .summary div { flex-direction: column; gap: 2px; }
        .summary dd { text-align: left; }
        .actions .btn { flex: 1; }
        /* Write the message comes first, straight under the prompt. */
        #cover-next { order: -1; }
        .flip { white-space: nowrap; padding: 10px 14px; }
        .preview-note { font-size: 12px; line-height: 1.4; }
      }
      @media (max-width: 400px) {
        .brand { gap: 8px; }
        .brand svg { width: 30px; height: 30px; }
        .brand span { font-size: 21px; }
        .top .btn.small { padding: 9px 14px; font-size: 14px; }
        .prompt input { font-size: 17px; }
      }
      @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
      }
