/* ==========================================================================
   startag.css — the proofing desk.

   Three panels, one artboard, nothing else (startag.md §4).

   THE DIRECTION, and why it changed.

   This shell used to be near-black with a blue-violet gradient on every primary
   control. That reads as a developer tool, and Startag's whole promise is that a
   stranger on mobile data can see it and know instantly that it is easy. So the
   surfaces are now drawn from the world the templates actually live in — print.
   Paper for the chrome, a warm desk tone for the stage, process inks for action.

   The artboard is a PROOF lying on a desk: square trim, a real shadow, and crop
   marks at its corners. The marks are not decoration — they show the trim edge
   of the file that will download, and they stay put while a design swaps, so
   tapping through the strip reads as new proofs laid into the same registration
   rather than the whole screen blinking.

   The original dark shell existed so light templates would pop. That still has
   to hold: --sg-desk is meaningfully deeper than --sg-paper, and the proof
   carries a hairline plus a layered shadow, so an ivory certificate reads as a
   distinct object and a navy campaign poster reads even harder.

   Layout contract (the JS depends on it — see startag.js boot()):
     desktop  ->  [ panel 356px ] [ stage 1fr / strip 138px ]
     mobile   ->  stage on top, strip under it, panel as a bottom sheet
   ========================================================================== */

.sg {
    /* Surfaces, named for what they are on the desk rather than for their
       lightness — it keeps the shell honest when a value gets tuned. */
    --sg-paper: #FCFBF9;
    --sg-paper-2: #F3F0EA;
    /* The desk has to sit well below the chrome in value, or an ivory template
       dissolves into it — which is the whole reason the shell used to be dark.
       This is the deepest it can go while still reading as daylight. */
    --sg-desk: #D5CEC1;

    /* Warm near-black. A blue-black would fight the paper. */
    --sg-ink: #17161B;
    --sg-ink-2: #4F4B45;
    --sg-ink-3: #74706A;

    --sg-rule: rgba(23, 22, 27, .10);
    --sg-rule-2: rgba(23, 22, 27, .18);

    /* Process inks. --sg-cyan carries white text and so is the darker of the
       two; --sg-cyan-lit is for rings and edges, which carry no text and can
       afford the brighter value. */
    --sg-cyan: #00658F;
    --sg-cyan-lit: #0086C9;
    --sg-cyan-deep: #005B82;
    --sg-cyan-wash: rgba(0, 134, 201, .12);

    /* Spent in exactly one place: "Surprise me". */
    --sg-magenta: #D6006C;

    --sg-amber: #F0B429;
    --sg-amber-ink: #3A2600;
    --sg-danger: #C0392B;

    --sg-display: Anton, "Arial Narrow", Impact, sans-serif;

    /*
     * The wordmark has its own face, separate from --sg-display.
     *
     * Anton is a poster type: built to be shouted at billboard size, and at the
     * 18px the header actually uses, its condensed counters close up and the
     * word reads as a dark block rather than as a name. It was also the same
     * face as the template headlines, so the product had no separation from the
     * artwork it makes.
     *
     * Bricolage Grotesque is a grotesque drawn with deliberate irregularity —
     * that slight wonk is what keeps it from feeling corporate, while the open
     * counters survive small sizes. Not Space Grotesk, which is the default
     * every product reaches for right now.
     */
    --sg-wordmark: "Bricolage Grotesque", "Segoe UI", Roboto, sans-serif;

    --sg-radius: 12px;
    --sg-radius-lg: 18px;
    --sg-header: 60px;
    --sg-strip: 138px;
    --sg-sheet-peek: 66px;
    --sg-ease: cubic-bezier(.22, .61, .36, 1);

    margin: 0;
    height: 100%;
    background: var(--sg-desk);
    color: var(--sg-ink);
    font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow: hidden;
    overscroll-behavior: none;
}

.sg *,
.sg *::before,
.sg *::after {
    box-sizing: border-box;
}

/*
 * The `hidden` attribute must always win.
 *
 * `hidden` only hides an element through the UA stylesheet's `display: none`,
 * so ANY author rule that sets display — `.sg-logout { display: inline-flex }`,
 * `.sg-btn { display: block }` — silently beats it. The JS sets `.hidden` on the
 * log-out button, the download button and the native-share button and quite
 * reasonably assumes they disappear; they did not.
 *
 * The visible symptom was a "Log out" button showing to visitors who had never
 * signed in, which then did nothing you could see: it dutifully logged out an
 * anonymous session and returned to an identical page.
 *
 * One rule rather than a `[hidden]` guard per component, because the next
 * component to be styled would have the same bug and nobody would notice.
 */
.sg [hidden] {
    display: none !important;
}

/* One focus treatment for the whole app. The old shell leaned on the browser
   default, which is close to invisible — and this page is judged on whether it
   feels finished. */
.sg :focus-visible {
    outline: 2px solid var(--sg-cyan-lit);
    outline-offset: 2px;
    border-radius: 4px;
}

.sg-app {
    display: grid;
    grid-template-rows: var(--sg-header) 1fr;
    height: 100vh;
    height: 100dvh;
    min-height: 0;
}

/* ---------------------------------------------------------------- header -- */

.sg-header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 22px;
    border-bottom: 1px solid var(--sg-rule);
    background: var(--sg-paper);
    z-index: 40;
}

/*
 * Sentence case, not uppercase.
 *
 * This is the single biggest change here and it is not about the typeface:
 * "REMIX" is a shout and "Remix" is a name. Uppercase also throws away the
 * only ascender and the only descender in the word, which is most of what
 * makes it recognisable at a glance in a browser tab or a favicon-sized space.
 *
 * The tracking goes with it. Anton needed +.05em to open up a condensed face;
 * a normal-width grotesque set in sentence case wants slightly negative, or
 * the letters drift apart and it stops reading as one word.
 */
.sg-logo {
    display: flex;
    align-items: center;
    gap: 11px;
    font-family: var(--sg-wordmark);
    font-size: 1.26rem;
    font-weight: 700;
    letter-spacing: -.012em;
    text-transform: none;
    white-space: nowrap;
}

/*
 * The lockup: REMIX with "by Brand AI" hanging off its lower right.
 *
 * The suffix is inline rather than absolutely positioned, so it reserves its
 * own width in the header and cannot ride over the separator beside it. The
 * drop is a transform rather than a margin for the same reason — it shifts the
 * baseline without changing the line box, so the mark stays vertically centred
 * against the buttons on the other side of the bar.
 */
.sg-logo__word {
    display: inline-flex;
    align-items: baseline;
}

.sg-logo__by {
    display: inline-block;
    margin-left: .42em;
    transform: translateY(.34em);
    font-family: Inter, sans-serif;
    font-size: .5rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: none;
    color: var(--sg-ink-3);
}

/* The Remix mark — a squared loop closing around a card. Drawn as SVG rather
   than pseudo-elements: it has to survive being scaled and recoloured, and a
   loop with arrowheads is past what two ::before/::after boxes can carry. */
.sg-logo__dot {
    flex: 0 0 auto;
    width: 23px;
    height: 23px;
    color: var(--sg-cyan);
}

.sg-logo__dot svg {
    display: block;
    width: 100%;
    height: 100%;
}

.sg-header__sep {
    width: 1px;
    height: 20px;
    background: var(--sg-rule-2);
}

/* Takes the slack so "Log out" and "Share it" group together on the right.
   Without this the auto margin on .sg-share strands Log out beside the title. */
.sg-header__title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .86rem;
    color: var(--sg-ink-2);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --------------------------------------------------- download + the gate -- */

.sg-download,
.sg-share {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 38px;
    margin-left: auto;
    padding: 0 18px;
    border: 1px solid transparent;
    border-radius: 999px;
    font: inherit;
    font-size: .86rem;
    font-weight: 700;
    white-space: nowrap;
    cursor: pointer;
    transition: transform .14s var(--sg-ease), box-shadow .14s var(--sg-ease),
                background .14s var(--sg-ease), border-color .14s var(--sg-ease);
}

.sg-download svg,
.sg-share svg {
    width: 16px;
    height: 16px;
}

.sg-share {
    border-color: var(--sg-rule-2);
    background: var(--sg-paper);
    color: var(--sg-ink);
}

.sg-share:hover {
    background: var(--sg-paper-2);
    border-color: var(--sg-ink-3);
}

.sg-share.is-busy {
    opacity: .55;
    pointer-events: none;
}

/* Share is the finish action, so it is the only filled control in the header. */
.sg-download,
.sg-share.sg-share--primary {
    background: var(--sg-cyan);
    border-color: var(--sg-cyan-deep);
    color: #fff;
    box-shadow: 0 1px 2px rgba(23, 22, 27, .14);
}

.sg-download:hover,
.sg-share.sg-share--primary:hover {
    background: var(--sg-cyan-deep);
    border-color: var(--sg-cyan-deep);
    transform: translateY(-1px);
    box-shadow: 0 8px 18px -8px rgba(0, 91, 130, .7);
}

.sg-download:active,
.sg-share.sg-share--primary:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(23, 22, 27, .14);
}

.sg-logout {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 38px;
    margin-left: 10px;
    padding: 0 14px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: transparent;
    color: var(--sg-ink-3);
    font: inherit;
    font-size: .82rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color .14s var(--sg-ease), background .14s var(--sg-ease);
}

.sg-logout:hover {
    color: var(--sg-ink);
    background: var(--sg-paper-2);
}

/* Share sits to the LEFT of Download, so only one of them pushes right. */
.sg-share + .sg-download {
    margin-left: 10px;
}

/* ------------------------------------------------------------ share sheet -- */

.sg-copyrow {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
}

.sg-copyrow input {
    flex: 1;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 10px;
    background: var(--sg-paper-2);
    color: var(--sg-ink-2);
    font: inherit;
    font-size: .84rem;
    text-overflow: ellipsis;
}

.sg-copyrow button {
    flex: 0 0 auto;
    height: 46px;
    padding: 0 18px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 10px;
    background: var(--sg-paper);
    color: var(--sg-ink);
    font: inherit;
    font-size: .86rem;
    font-weight: 700;
    cursor: pointer;
    transition: border-color .14s var(--sg-ease), background .14s var(--sg-ease);
}

.sg-copyrow button:hover {
    border-color: var(--sg-cyan-lit);
    background: var(--sg-cyan-wash);
}

.sg-sharegrid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin: 16px 0 14px;
}

.sg-sharebtn {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 10px;
    background: var(--sg-paper);
    color: var(--sg-ink);
    font-size: .82rem;
    font-weight: 600;
    text-decoration: none;
    transition: border-color .14s var(--sg-ease), background .14s var(--sg-ease),
                transform .14s var(--sg-ease);
}

.sg-sharebtn:hover {
    border-color: var(--sg-cyan-lit);
    background: var(--sg-cyan-wash);
    transform: translateY(-1px);
}

.sg-sharenote {
    margin: 0 0 18px;
    font-size: .76rem;
    line-height: 1.55;
    color: var(--sg-ink-3);
}

.sg-sharenote strong {
    color: var(--sg-ink-2);
}

.sg-sharenote a {
    color: var(--sg-cyan-deep);
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap;
}

/* ---------------------------------------------------------------- modals -- */

.sg-gate,
.sg-sharesheet,
.sg-auth {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(23, 22, 27, .46);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    opacity: 0;
    transition: opacity .18s var(--sg-ease);
}

.sg-gate.is-open,
.sg-sharesheet.is-open,
.sg-auth.is-open {
    opacity: 1;
}

.sg-gate[hidden],
.sg-sharesheet[hidden],
.sg-auth[hidden] {
    display: none;
}

.sg-gate__card {
    width: 100%;
    max-width: 412px;
    max-height: calc(100dvh - 48px);
    overflow-y: auto;
    padding: 32px 30px 26px;
    border-radius: var(--sg-radius-lg);
    background: var(--sg-paper);
    box-shadow:
        0 0 0 1px var(--sg-rule),
        0 32px 70px -26px rgba(23, 22, 27, .5),
        0 8px 22px -12px rgba(23, 22, 27, .3);
    text-align: center;
    transform: translateY(10px) scale(.985);
    transition: transform .2s var(--sg-ease);
}

.sg-gate.is-open .sg-gate__card,
.sg-sharesheet.is-open .sg-gate__card {
    transform: none;
}

.sg-gate__title {
    margin: 0 0 10px;
    font-size: 1.34rem;
    font-weight: 800;
    letter-spacing: -.015em;
    color: var(--sg-ink);
}

.sg-gate__body {
    margin: 0 0 22px;
    font-size: .92rem;
    line-height: 1.55;
    color: var(--sg-ink-2);
}

.sg-auth__card {
    width: min(440px, calc(100vw - 28px));
    min-height: 0;
    display: flex;
    flex-direction: column;
    border-radius: var(--sg-radius-lg);
    background: var(--sg-paper);
    box-shadow:
        0 0 0 1px var(--sg-rule),
        0 32px 70px -26px rgba(23, 22, 27, .5),
        0 8px 22px -12px rgba(23, 22, 27, .3);
    overflow: hidden;
    transform: translateY(10px) scale(.985);
    transition: transform .2s var(--sg-ease);
}

.sg-auth.is-open .sg-auth__card {
    transform: none;
}

.sg-auth__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 24px 16px;
    border-bottom: 1px solid var(--sg-rule);
    text-align: left;
}

.sg-auth__head .sg-gate__body {
    margin-bottom: 0;
}

.sg-auth__body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 24px;
}

.sg-auth__close {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 999px;
    background: transparent;
    color: var(--sg-ink-3);
    font: inherit;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    transition: color .14s var(--sg-ease), background .14s var(--sg-ease);
}

.sg-auth__close:hover {
    color: var(--sg-ink);
    background: var(--sg-paper-2);
}

.sg-auth__loader {
    display: none;
    width: 42px;
    height: 42px;
    margin: 18px auto 0;
    border: 3px solid var(--sg-rule);
    border-top-color: var(--sg-cyan);
    border-radius: 50%;
    animation: sg-spin .8s linear infinite;
}

.sg-auth.is-loading .sg-auth__loader {
    display: block;
}

.sg-auth__note {
    margin: 12px 2px 0;
    font-size: .78rem;
    line-height: 1.55;
    color: var(--sg-ink-3);
}

@keyframes sg-spin {
    to { transform: rotate(360deg); }
}

/* --------------------------------------------------------------- buttons -- */

.sg-btn {
    display: block;
    width: 100%;
    height: 50px;
    line-height: 50px;
    border: 1px solid transparent;
    border-radius: 11px;
    font: inherit;
    font-size: .94rem;
    font-weight: 700;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: transform .14s var(--sg-ease), background .14s var(--sg-ease),
                border-color .14s var(--sg-ease), box-shadow .14s var(--sg-ease);
}

.sg-btn.sg-btn--icon {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    line-height: normal;
}

.sg-btn.sg-btn--icon svg {
    width: 17px;
    height: 17px;
}

.sg-btn--primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--sg-cyan);
    border-color: var(--sg-cyan-deep);
    color: #fff;
    box-shadow: 0 1px 2px rgba(23, 22, 27, .14);
}

.sg-btn--primary:hover {
    background: var(--sg-cyan-deep);
    transform: translateY(-1px);
    box-shadow: 0 10px 22px -10px rgba(0, 91, 130, .7);
}

.sg-btn--primary:active {
    transform: translateY(0);
}

.sg-btn--ghost {
    margin-top: 10px;
    height: 44px;
    line-height: 42px;
    background: transparent;
    border-color: transparent;
    color: var(--sg-ink-3);
    font-weight: 600;
}

.sg-btn--ghost:hover {
    color: var(--sg-ink);
    background: var(--sg-paper-2);
}

.sg-btn--google {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding-left: 48px;
    padding-right: 20px;
    background: var(--sg-paper);
    color: var(--sg-ink);
    border-color: var(--sg-rule-2);
    box-shadow: 0 1px 2px rgba(23, 22, 27, .08);
}

.sg-btn--google svg {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    position: absolute;
    left: 18px;
}

.sg-btn--google:hover {
    border-color: var(--sg-ink-3);
    background: var(--sg-paper-2);
    transform: none;
}

.sg-btn--google.is-busy,
.sg-btn--google[disabled] {
    opacity: .6;
    cursor: default;
    transform: none;
}

/*
 * Download is the SECONDARY action in this sheet.
 *
 * It ships as .sg-btn--primary in the markup, which stacked two identical
 * filled buttons and left the sheet with two competing primaries. growth.md
 * §3.2 is explicit that the gate belongs on the lower-value action and that
 * sharing is the finish action, so share stays filled and this steps back to an
 * outline. Restyled here rather than by changing the class, so the JS that
 * looks the button up keeps working untouched.
 */
.sg-sharesheet [data-sg-download] {
    margin-bottom: 10px;
    background: var(--sg-paper);
    border-color: var(--sg-rule-2);
    color: var(--sg-ink);
    box-shadow: none;
}

.sg-sharesheet [data-sg-download]:hover {
    background: var(--sg-paper-2);
    border-color: var(--sg-ink-3);
    box-shadow: none;
}

/* --------------------------------------------------------- unlock by email -- */

.sg-unlock[hidden] {
    display: none;
}

.sg-unlock {
    margin: 8px 0 16px;
    text-align: left;
}

.sg-unlock__divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 14px;
    color: var(--sg-ink-3);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.sg-unlock__divider::before,
.sg-unlock__divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--sg-rule);
}

.sg-unlock__row {
    display: flex;
    gap: 8px;
}

.sg-unlock__row input {
    flex: 1;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 10px;
    background: var(--sg-paper-2);
    color: var(--sg-ink);
    font: inherit;
    font-size: .88rem;
}

.sg-unlock__row input::placeholder {
    color: var(--sg-ink-3);
}

.sg-unlock__row input:focus {
    outline: none;
    border-color: var(--sg-cyan-lit);
    background: var(--sg-paper);
    box-shadow: 0 0 0 3px var(--sg-cyan-wash);
}

.sg-unlock__row button {
    flex: 0 0 auto;
    height: 46px;
    padding: 0 18px;
    border: 1px solid var(--sg-cyan-deep);
    border-radius: 10px;
    background: var(--sg-cyan);
    color: #fff;
    font: inherit;
    font-size: .86rem;
    font-weight: 700;
    cursor: pointer;
    transition: background .14s var(--sg-ease), transform .14s var(--sg-ease),
                opacity .14s var(--sg-ease);
}

.sg-unlock__row button:hover {
    background: var(--sg-cyan-deep);
    transform: translateY(-1px);
}

.sg-unlock__row button[disabled] {
    opacity: .55;
    cursor: default;
    transform: none;
}

.sg-unlock__note {
    margin: 10px 2px 0;
    font-size: .76rem;
    line-height: 1.5;
    color: var(--sg-ink-3);
}

/* ----------------------------------------------------------------- toast -- */
/* Ink on paper is the app; the toast inverts so a system message never reads as
   part of the design work. */

.sg-toast {
    position: fixed;
    left: 50%;
    bottom: 30px;
    z-index: 300;
    transform: translate(-50%, 12px);
    max-width: min(420px, calc(100vw - 32px));
    padding: 13px 20px;
    border-radius: 11px;
    background: var(--sg-ink);
    color: var(--sg-paper);
    font-size: .87rem;
    box-shadow: 0 20px 44px -20px rgba(23, 22, 27, .7);
    opacity: 0;
    transition: opacity .2s var(--sg-ease), transform .2s var(--sg-ease);
}

.sg-toast.is-open {
    opacity: 1;
    transform: translate(-50%, 0);
}

/* ------------------------------------------------------------------ main -- */

.sg-main {
    display: grid;
    grid-template-columns: 356px 1fr;
    min-height: 0;
    min-width: 0;
}

.sg-right {
    display: grid;
    grid-template-rows: 1fr var(--sg-strip);
    min-height: 0;
    min-width: 0;
}

/* --------------------------------------------------------- panel 1: form -- */

.sg-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--sg-paper);
    border-right: 1px solid var(--sg-rule);
}

.sg-panel__head {
    padding: 22px 26px 16px;
    border-bottom: 1px solid var(--sg-rule);
}

/* Anton, because it is the face the posters themselves are set in — the tool
   speaking the same language as the thing it makes. Already in the payload, so
   it costs nothing. Kept to headings only; Inter carries all real reading. */
.sg-panel__title {
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: var(--sg-display);
    font-size: .84rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--sg-ink);
}

.sg-panel__title svg {
    width: 14px;
    height: 14px;
    color: var(--sg-cyan);
}

.sg-panel__hint {
    margin: 8px 0 0;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--sg-ink-3);
}

.sg-panel__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 22px 26px 44px;
    scrollbar-width: thin;
    scrollbar-color: var(--sg-rule-2) transparent;
}

.sg-panel__body::-webkit-scrollbar {
    width: 10px;
}

.sg-panel__body::-webkit-scrollbar-track {
    background: transparent;
}

/* Inset by a transparent border so the thumb reads as a hairline, not a rail. */
.sg-panel__body::-webkit-scrollbar-thumb {
    background: rgba(23, 22, 27, .16);
    background-clip: content-box;
    border: 4px solid transparent;
    border-radius: 999px;
}

.sg-panel__body::-webkit-scrollbar-thumb:hover {
    background: rgba(23, 22, 27, .3);
    background-clip: content-box;
}

/* ----------------------------------------------------------------- field -- */

.sg-field {
    position: relative;
    margin-bottom: 20px;
}

.sg-field__label {
    display: block;
    margin: 0 0 8px 2px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--sg-ink-3);
    transition: color .16s var(--sg-ease);
}

.sg-field.is-active .sg-field__label {
    color: var(--sg-cyan-deep);
}

.sg-field__input {
    display: block;
    width: 100%;
    min-height: 50px;
    max-height: 200px;
    padding: 13px 15px;
    border: 1px solid var(--sg-rule-2);
    border-radius: var(--sg-radius);
    background: var(--sg-paper-2);
    color: var(--sg-ink);
    font: inherit;
    font-size: .98rem;
    line-height: 1.4;
    resize: none;
    overflow: hidden;
    transition: border-color .16s var(--sg-ease), box-shadow .16s var(--sg-ease),
                background .16s var(--sg-ease);
}

.sg-field__input::placeholder {
    color: var(--sg-ink-3);
}

.sg-field__input:hover {
    border-color: var(--sg-ink-3);
}

.sg-field__input:focus {
    outline: none;
    border-color: var(--sg-cyan-lit);
    background: var(--sg-paper);
    box-shadow: 0 0 0 3px var(--sg-cyan-wash);
}

.sg-field__count {
    position: absolute;
    right: 12px;
    bottom: -17px;
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
    color: var(--sg-ink-3);
    opacity: 0;
    transition: opacity .16s var(--sg-ease), color .16s var(--sg-ease);
    pointer-events: none;
}

.sg-field__count.is-shown {
    opacity: 1;
}

.sg-field__count.is-over {
    color: var(--sg-danger);
    font-weight: 700;
}

/* ---------------------------------------------------------------- photos -- */

.sg-photo {
    margin-bottom: 10px;
}

.sg-drop {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 132px;
    padding: 12px;
    border: 1px dashed var(--sg-rule-2);
    border-radius: var(--sg-radius);
    background: var(--sg-paper-2) center/cover no-repeat;
    color: var(--sg-ink-3);
    font: inherit;
    font-size: .84rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .16s var(--sg-ease), background-color .16s var(--sg-ease),
                color .16s var(--sg-ease), transform .16s var(--sg-ease);
}

.sg-drop:hover,
.sg-drop.is-over {
    border-color: var(--sg-cyan-lit);
    background-color: var(--sg-cyan-wash);
    color: var(--sg-cyan-deep);
}

.sg-drop.is-filled {
    border-style: solid;
    border-color: var(--sg-rule-2);
}

.sg-drop.is-filled .sg-drop__hint {
    opacity: 0;
}

.sg-drop.is-filled:hover .sg-drop__hint {
    opacity: 1;
    padding: 7px 12px;
    border-radius: 8px;
    background: rgba(23, 22, 27, .82);
    color: var(--sg-paper);
}

.sg-drop.is-pulse {
    animation: sg-pulse .7s var(--sg-ease);
}

.sg-drop__hint {
    pointer-events: none;
    transition: opacity .16s var(--sg-ease);
}

@keyframes sg-pulse {
    0%, 100% { transform: scale(1); border-color: var(--sg-rule-2); }
    35%      { transform: scale(1.02); border-color: var(--sg-cyan-lit); }
}

.sg-search {
    margin-top: 12px;
}

.sg-search__input {
    width: 100%;
    height: 44px;
    padding: 8px 14px;
    border: 1px solid var(--sg-rule-2);
    border-radius: 10px;
    background: var(--sg-paper-2);
    color: var(--sg-ink);
    font: inherit;
    font-size: .9rem;
}

.sg-search__input::placeholder {
    color: var(--sg-ink-3);
}

.sg-search__input:focus {
    outline: none;
    border-color: var(--sg-cyan-lit);
    background: var(--sg-paper);
    box-shadow: 0 0 0 3px var(--sg-cyan-wash);
}

.sg-search__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 7px;
    margin-top: 12px;
}

.sg-search__grid.is-loading {
    opacity: .45;
}

.sg-search__empty {
    grid-column: 1 / -1;
    margin: 4px 0 0;
    font-size: .8rem;
    color: var(--sg-ink-3);
}

.sg-shot {
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 1px solid var(--sg-rule);
    border-radius: 8px;
    background: var(--sg-paper-2) center/cover no-repeat;
    cursor: pointer;
    transition: transform .14s var(--sg-ease), box-shadow .14s var(--sg-ease);
}

.sg-shot:hover {
    transform: scale(1.06);
    box-shadow: 0 0 0 2px var(--sg-cyan-lit);
}

/*
 * Attribution. The Pexels licence requires the photographer to be credited and
 * linked wherever their photos are used, so these are deliberately visible
 * rather than tucked into a tooltip — but kept quiet enough that they never
 * compete with the design work.
 */

.sg-credit,
.sg-search__credit {
    margin: 8px 0 0;
    font-size: .74rem;
    line-height: 1.45;
    color: var(--sg-ink-3);
}

.sg-credit[hidden] {
    display: none;
}

.sg-credit a,
.sg-search__credit a {
    color: var(--sg-ink-2);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.sg-credit a:hover,
.sg-search__credit a:hover {
    color: var(--sg-cyan-deep);
}

/* -------------------------------------------------------------- palettes -- */

.sg-subhead {
    margin: 30px 0 14px 2px;
    padding-top: 22px;
    border-top: 1px solid var(--sg-rule);
    font-family: var(--sg-display);
    font-size: .78rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--sg-ink-3);
}

/* Sized so a full shelf of six fits on one row at the panel's width — a palette
   that wraps reads as a list to work through rather than a row to flick along. */
.sg-palette {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* A swatch is the palette in miniature — the surface it paints, with its accent
   sitting on top — not an abstract colour chip. */
.sg-swatch {
    position: relative;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 1px solid var(--sg-rule-2);
    border-radius: 50%;
    background: var(--sg-sw-bg, #222);
    cursor: pointer;
    transition: transform .16s var(--sg-ease), box-shadow .16s var(--sg-ease);
}

.sg-swatch::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--sg-sw-ac, #fff);
    transform: translate(-50%, -50%);
}

.sg-swatch:hover {
    transform: translateY(-2px) scale(1.06);
    box-shadow: 0 6px 14px -6px rgba(23, 22, 27, .5);
}

.sg-swatch.is-current {
    box-shadow: 0 0 0 2px var(--sg-paper), 0 0 0 4px var(--sg-cyan-lit);
}

/* ------------------------------------------------------- panel 2: stage -- */

.sg-stage {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
    min-width: 0;
    padding: 64px;
    /* A vignette rather than a top-light: darkening the edges frames the proof
       and keeps the centre the brightest thing on the desk. A bright wash at the
       top did the opposite — it pulled the desk up to the panel's value and the
       artboard lost its edge. */
    background:
        radial-gradient(70% 66% at 50% 46%, rgba(255, 253, 249, .42), transparent 72%),
        radial-gradient(130% 110% at 50% 50%, transparent 58%, rgba(23, 22, 27, .07)),
        var(--sg-desk);
}

.sg-stage__frame {
    position: relative;
    line-height: 0;
    /* Square trim: a printed proof has no rounded corners, and the crop marks
       below only read correctly against a straight edge. */
    box-shadow:
        0 0 0 1px rgba(23, 22, 27, .13),
        0 30px 60px -22px rgba(23, 22, 27, .45),
        0 8px 20px -10px rgba(23, 22, 27, .28);
    animation: sg-lay .42s var(--sg-ease) both;
}

/*
 * THE SIGNATURE — crop marks.
 *
 * Four registration marks set off the corners, exactly as a printer marks the
 * trim on a proof. They are information, not ornament: they show the trim edge
 * of the file that downloads. Eight 1px gradient layers on one pseudo-element,
 * which stays crisp at any zoom and needs no markup.
 *
 * They live outside the frame and are NOT faded during a template swap (see
 * is-swapping below), so the registration holds while the design changes.
 */
.sg-stage__frame::before {
    --sg-mark: 16px;
    --sg-mark-ink: rgba(23, 22, 27, .42);

    content: "";
    position: absolute;
    inset: -22px;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink)),
        linear-gradient(var(--sg-mark-ink), var(--sg-mark-ink));
    background-size:
        var(--sg-mark) 1px, 1px var(--sg-mark),   /* top-left    */
        var(--sg-mark) 1px, 1px var(--sg-mark),   /* top-right   */
        var(--sg-mark) 1px, 1px var(--sg-mark),   /* bottom-left */
        var(--sg-mark) 1px, 1px var(--sg-mark);   /* bottom-right*/
    background-position:
        left top, left top,
        right top, right top,
        left bottom, left bottom,
        right bottom, right bottom;
}

.sg-stage__frame .canvas-container {
    display: block !important;
    transition: opacity .2s var(--sg-ease);
}

.sg-stage__frame canvas {
    display: block;
}

/* Only the artwork fades on a swap. The marks hold their registration. */
.sg.is-swapping .sg-stage__frame .canvas-container {
    opacity: 0;
}

/* "Surprise me" reshuffles the design — the proof lifts as if it were lifted
   off the desk and set back down. Replaces the old opacity blink. */
.sg-stage__frame.is-flash {
    animation: sg-lift .34s var(--sg-ease);
}

@keyframes sg-lay {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes sg-lift {
    0%, 100% { transform: scale(1); }
    45%      { transform: scale(1.012); }
}

.sg-stage__empty {
    max-width: 320px;
    text-align: center;
    color: var(--sg-ink-3);
    font-size: .9rem;
    line-height: 1.6;
}

/* ----------------------------------------------------------- surprise me -- */
/* The one playful control on the page, and the only place magenta appears. */

.sg-surprise {
    position: absolute;
    right: 28px;
    bottom: 26px;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    padding: 0 20px;
    border: 1px solid rgba(23, 22, 27, .12);
    border-radius: 999px;
    background: var(--sg-magenta);
    color: #fff;
    font: inherit;
    font-size: .88rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 10px 24px -10px rgba(214, 0, 108, .65), 0 1px 2px rgba(23, 22, 27, .18);
    transition: transform .16s var(--sg-ease), box-shadow .16s var(--sg-ease);
}

.sg-surprise:hover {
    transform: translateY(-2px);
    box-shadow: 0 16px 30px -12px rgba(214, 0, 108, .75), 0 1px 2px rgba(23, 22, 27, .18);
}

.sg-surprise:active {
    transform: translateY(0) scale(.97);
}

.sg-surprise__spark {
    font-size: .98rem;
}

/* -------------------------------------------------------- panel 3: strip -- */
/* The contact sheet: finished proofs laid out on a paper tray. */

.sg-strip {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
    border-top: 1px solid var(--sg-rule);
    background: var(--sg-paper);
}

.sg-strip__rail {
    display: flex;
    align-items: center;
    gap: 14px;
    height: 100%;
    padding: 0 22px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

.sg-strip__rail::-webkit-scrollbar {
    display: none;
}

.sg-group {
    position: relative;
    align-self: center;
    flex: 0 0 auto;
    font-family: var(--sg-display);
    font-size: .72rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--sg-ink-3);
    white-space: nowrap;
}

/* A rule, not a pill: it separates runs on the shelf without adding another
   rounded box to a screen that already has plenty. */
.sg-group:not(:first-child) {
    margin-left: 20px;
    padding-left: 22px;
}

.sg-group:not(:first-child)::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 26px;
    background: var(--sg-rule-2);
    transform: translateY(-50%);
}

.sg-tpl {
    position: relative;
    flex: 0 0 auto;
    height: 96px;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: var(--sg-paper-2);
    cursor: pointer;
    overflow: hidden;
    scroll-snap-align: center;
    box-shadow: 0 0 0 1px var(--sg-rule), 0 2px 6px -3px rgba(23, 22, 27, .3);
    transition: transform .18s var(--sg-ease), box-shadow .18s var(--sg-ease);
}

.sg-tpl::before {
    /* shimmer placeholder until the thumbnail is rendered */
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, #EDE9E2 30%, #F7F4EF 50%, #EDE9E2 70%);
    background-size: 220% 100%;
    animation: sg-shimmer 1.3s linear infinite;
}

.sg-tpl.is-ready::before {
    content: none;
}

.sg-tpl img {
    display: block;
    height: 100%;
    width: auto;
    opacity: 0;
    transition: opacity .3s var(--sg-ease);
}

.sg-tpl.is-ready img {
    opacity: 1;
}

.sg-tpl:hover {
    transform: translateY(-4px);
    box-shadow: 0 0 0 1px var(--sg-rule-2), 0 14px 26px -12px rgba(23, 22, 27, .5);
}

.sg-tpl.is-current {
    box-shadow: 0 0 0 2px var(--sg-cyan-lit), 0 10px 20px -12px rgba(23, 22, 27, .45);
}

.sg-tpl__urgency {
    position: absolute;
    top: 5px;
    left: 5px;
    right: 5px;
    padding: 3px 5px;
    border-radius: 4px;
    background: var(--sg-amber);
    color: var(--sg-amber-ink);
    font-size: .56rem;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    z-index: 2;
}

/* Sits over the artwork, so it stays dark whatever the shell does. */
.sg-tpl__name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 16px 8px 7px;
    background: linear-gradient(to top, rgba(23, 22, 27, .86), transparent);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    opacity: 0;
    transition: opacity .18s var(--sg-ease);
}

.sg-tpl:hover .sg-tpl__name,
.sg-tpl.is-current .sg-tpl__name {
    opacity: 1;
}

/* placeholder keeping the rail from ever ending flush (startag.md §8.4) */
.sg-strip__tease {
    flex: 0 0 auto;
    width: 50px;
    height: 96px;
    border: 1px dashed var(--sg-rule-2);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--sg-ink-3);
    font-size: .62rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-align: center;
    line-height: 1.25;
}

.sg-strip__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--sg-rule-2);
    border-radius: 50%;
    background: var(--sg-paper);
    color: var(--sg-ink);
    cursor: pointer;
    opacity: 0;
    box-shadow: 0 4px 12px -4px rgba(23, 22, 27, .35);
    transition: opacity .18s var(--sg-ease), background .18s var(--sg-ease);
}

.sg-strip:hover .sg-strip__arrow,
.sg-strip__arrow:focus-visible {
    opacity: 1;
}

.sg-strip__arrow:hover {
    background: var(--sg-paper-2);
}

.sg-strip__arrow--prev { left: 12px; }
.sg-strip__arrow--next { right: 12px; }

.sg-strip__arrow svg {
    width: 16px;
    height: 16px;
}

@keyframes sg-shimmer {
    from { background-position: 140% 0; }
    to   { background-position: -40% 0; }
}

/* ----------------------------------------------------- mobile: stacked --- */

.sg-sheet__grab {
    display: none;
}

@media (max-width: 900px) {
    .sg {
        --sg-strip: 112px;
        --sg-header: 56px;
        --sg-sheet-peek: 66px;
    }

    .sg-main {
        grid-template-columns: 1fr;
        position: relative;
    }

    .sg-right {
        grid-template-rows: 1fr var(--sg-strip);
        padding-bottom: var(--sg-sheet-peek);
    }

    .sg-stage {
        padding: 30px 24px;
    }

    /* Marks pull in with the padding so they never clip against the stage. */
    .sg-stage__frame::before {
        --sg-mark: 11px;
        inset: -15px;
    }

    .sg-header {
        padding: 0 16px;
    }

    /* Panel becomes a bottom sheet: peeking by default, dragged or tapped up. */
    .sg-panel {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 50;
        height: 74vh;
        max-height: 580px;
        border-right: 0;
        border-top: 1px solid var(--sg-rule);
        border-radius: 20px 20px 0 0;
        background: var(--sg-paper);
        box-shadow: 0 -16px 40px -18px rgba(23, 22, 27, .35);
        transform: translateY(calc(100% - var(--sg-sheet-peek)));
        transition: transform .3s var(--sg-ease);
        touch-action: none;
    }

    .sg-panel.is-open {
        transform: translateY(0);
    }

    .sg-panel.is-dragging {
        transition: none;
    }

    .sg-sheet__grab {
        position: relative;
        display: flex;
        align-items: center;
        gap: 10px;
        flex: 0 0 auto;
        height: var(--sg-sheet-peek);
        padding: 6px 22px 0;
        cursor: grab;
        user-select: none;
        -webkit-user-select: none;
    }

    .sg-sheet__grab::before {
        content: "";
        position: absolute;
        top: 9px;
        left: 50%;
        transform: translateX(-50%);
        width: 40px;
        height: 4px;
        border-radius: 99px;
        background: var(--sg-rule-2);
    }

    .sg-sheet__grab-label {
        font-family: var(--sg-display);
        font-size: .84rem;
        letter-spacing: .14em;
        text-transform: uppercase;
    }

    .sg-sheet__grab-sub {
        margin-left: auto;
        font-size: .78rem;
        font-weight: 600;
        color: var(--sg-cyan-deep);
    }

    /* the grab bar already says "Your details" — don't say it twice */
    .sg-panel__title {
        display: none;
    }

    .sg-panel__head {
        padding: 2px 22px 14px;
    }

    .sg-panel__body {
        padding: 18px 22px calc(30px + env(safe-area-inset-bottom, 0px));
        touch-action: pan-y;
    }

    .sg-surprise {
        right: 18px;
        bottom: 18px;
        height: 42px;
        padding: 0 17px;
    }

    .sg-strip__arrow {
        display: none;
    }

    .sg-tpl,
    .sg-strip__tease {
        height: 80px;
    }

    .sg-header__sep,
    .sg-header__title {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .sg *,
    .sg *::before,
    .sg *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}
