/**
 * gcc-creator.css — the card-composing interface, written from scratch.
 *
 * IT REPLACES three files: iphone-chat.css (728 lines), gcc-chat-mode.css (1326)
 * and gcc-layout-center.css (573 lines of override). The first two built a fake
 * iPhone — the case, the notch, the status bar, the home indicator — with :not()
 * chains at 0,9,1 plus !important. The new layout uses no device case, so all of
 * that is only an obstacle: every small change needed a more specific override
 * still. Dropped entirely, not one !important is needed.
 *
 * Colours come from the page's tokens (css/theme.css) and so are right in both
 * light and dark — the old version hard-coded dark colours because it always sat on a white "screen".
 */

/* ══════════════════════════════════════════════════════════════════════════
 * 1. LAYOUT — one column, the preview in the middle, the compose box below
 * ══════════════════════════════════════════════════════════════════════════ */
/* ══════════════════════════════════════════════════════════════════════════
 * THIS FILE'S OWN TOKEN SET
 * ══════════════════════════════════════════════════════════════════════════
 * The floating panels (the quota panel, the confirm box, the account slide-out)
 * must NEVER use --ink / --card / --surface-2. Measured on the real page: inside
 * the chat frame --ink resolved to #333333 and --card to WHITE, though on <body>
 * --card is #161616 — the token is redefined at a nearer level. The result was
 * #333 text on #1c1c1e, a contrast of 1.28: it sank into the black.
 * The gcc-pnl- prefix keeps the names clear of every other token set.
 * The grounds have to be OPAQUE: a few rules in this project use a ground token as a TEXT colour. */
:root {
    /* The send arrow: rounded strokes, the same visual language as the other icons
       on the page (2px stroke, rounded caps). Kept in a variable so it is declared
       once and edited in one place. */
    --gcc-icon-gui: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20V5'/%3E%3Cpath d='M5 12l7-7 7 7'/%3E%3C/svg%3E");
    --gcc-pnl-bg: #ffffff;
    --gcc-pnl-fg: #1a1a1a;
    --gcc-pnl-line: rgba(0, 0, 0, .14);
}

:root[data-theme="dark"],
:root:not([data-theme="light"]) {
    --gcc-pnl-bg: #1c1c1e;
    --gcc-pnl-fg: #ececec;
    --gcc-pnl-line: rgba(127, 127, 127, .3);
}

/* ══════════════════════════════════════════════════════════════════════════
 * 0. THE VERTICAL NAVIGATION RAIL (js/gcc-sidebar.js)
 * ══════════════════════════════════════════════════════════════════════════ */

/* The width lives in ONE place: both the sidebar and the workspace inset read
   this variable. Two separate numbers drift apart eventually, and this kind of
   drift shows up as content sliding under the rail. */
:root { --gcc-sb-w: 232px; }
body.gcc-sb-collapsed { --gcc-sb-w: 56px; }

.gcc-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 120;
    width: var(--gcc-sb-w);
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 8px;
    box-sizing: border-box;
    /* Opaque, not transparent: the workspace scrolls right beside it, and a
       transparent ground leaves text drifting faintly behind the navigation items. */
    background: #141414;
    border-right: 1px solid rgba(127, 127, 127, .16);
    color: #e8e8e8;
    font-size: 13.5px;
    overflow: hidden;
    transition: width .16s ease;
}

:root[data-theme="light"] .gcc-sidebar {
    background: #f7f7f7;
    color: #1a1a1a;
}

/* The workspace insets by exactly the rail width. The rail is position:fixed and
   so takes no space in the flow — without this line it covers the left column. */
body.gcc-has-sidebar .gcc-page-wrap { padding-left: var(--gcc-sb-w); }

/* ── WHERE THE RAIL APPEARS, WHICH IS NOT THE SAME ON BOTH ─────────────────
   On a DESKTOP nothing has changed: the rail is on every page, because there is
   room for it beside the work and it costs a task nothing.

   On a PHONE it is on the home page only. A second navigation sitting on top of
   a screen whose entire job is one task is what stuck open in the editor — and
   in the editor it was literally on top, over the card being made. So the phone
   gets a hub: home navigates, every other screen is one thing with a way back.

   Two classes rather than two versions of a page. `gcc-sb-desktop-only` on the
   sub-pages, `gcc-sb-mobile-only` on the home page — the same components, one
   line deciding which screen shows them.

   The padding goes with it. Hiding the rail while the page still reserves 52px
   would leave a phone with an empty stripe down its side. */
@media (max-width: 900px) {
    body.gcc-sb-desktop-only .gcc-sidebar { display: none; }
    body.gcc-sb-desktop-only .gcc-page-wrap { padding-left: 0; }

    /* ── ON A PHONE THE RAIL IS A DRAWER, AND IT STARTS SHUT ───────────────
       A 52px strip of icons was showing on the home page at all times: it took
       a seventh of a 375px screen to say nothing — an icon with no word beside
       it is a guess, and seven of them are seven guesses down the side of the
       page somebody came to read.

       So: nothing until it is asked for, and when it is asked for, EVERYTHING —
       icons WITH their labels, at the full 232px. A drawer that opens to a
       narrow strip of pictures would be the same problem with an extra tap in
       front of it.

       The page keeps its whole width because the drawer is `position: fixed` and
       floats over: no padding is reserved for something that is not there. */
    body.gcc-sb-mobile-only .gcc-page-wrap { padding-left: 0; }

    body.gcc-sb-mobile-only .gcc-sidebar {
        /* `left`, not `transform`. The transform version was written first and
           did not open: the closed state applied and the open state did not,
           while the browser reported NO rule with a transform matching this
           element at all — the two answers cannot both be true, so something
           else owns that property here and finding it is a longer errand than
           this is worth.

           `left` is owned by nobody else on this element, and for a panel fixed
           to the edge of the screen it says the same thing more plainly. */
        left: -232px;
        transition: left .24s cubic-bezier(.22, .9, .3, 1);
        z-index: 60;
        /* The full width WHATEVER the desktop's collapsed preference is: that
           choice is about a rail beside the work, and this is a drawer over it. */
        width: 232px;
    }
    body.gcc-sb-mobile-only.gcc-sb-open .gcc-sidebar { left: 0; }

    /* The labels come back even when the desktop is left collapsed, for the same
       reason: `body.gcc-sb-collapsed .gcc-sb-text { display: none }` is a rail's
       rule, and this is not a rail. */
    body.gcc-sb-mobile-only .gcc-sb-text { display: inline; }
    /* `flex`, which is the brand's OWN value — this line read `display: block`
       and stacked the envelope on top of the word. Reported with a screenshot of
       exactly that.

       The line has to exist: `body.gcc-sb-collapsed .gcc-sb-brand { display:
       none }` hides the brand for a collapsed rail, and somebody who left the
       desktop collapsed would open this drawer to a nameless list. Restoring a
       hidden element means restoring the display it had, not choosing a new one. */
    body.gcc-sb-mobile-only .gcc-sb-brand { display: flex; }
    body.gcc-sb-mobile-only .gcc-sb-item,
    body.gcc-sb-mobile-only .gcc-sb-user { justify-content: flex-start; padding-inline: 8px; }
    /* The collapse control belongs to the desktop rail; in a drawer there is
       nothing to collapse to. */
    body.gcc-sb-mobile-only .gcc-sb-toggle { display: none; }

    /* The way in, and the way out. */
    .gcc-sb-launch,
    .gcc-sb-back {
        /* IN LINE WITH THE BRAND, not floating above it.
           `top: 10px` put the button higher than PHATTT itself — reported with a
           screenshot. The header's own row starts at `.wrap`'s 20px padding plus
           `header.top`'s 12px, and `align-items: center` puts the brand's middle
           at about 50px down; a 40px button centred on that begins at 30.

           `left` repeats `.wrap`'s own horizontal padding expression rather than
           a number, so the button stays on the same left edge as the brand at
           every width — copying the value would drift the first time that clamp
           is touched. */
        position: fixed;
        /* 33, not the 30 the arithmetic suggested: measured on the live page the
           brand's centre sits at 53 and a 40px button starting at 30 centres on
           50. Three pixels, and the reason to spend a line on them is that the
           eye reads a row as a row or as two things at slightly different
           heights, with nothing in between. */
        top: calc(33px + env(safe-area-inset-top, 0px));
        left: clamp(18px, 4vw, 40px);
        z-index: 61;
        width: 40px; height: 40px;
        display: grid; place-items: center;
        padding: 0;
        border: 1px solid var(--gcc-line, #2b2f39);
        border-radius: 11px;
        background: var(--gcc-surface-1, #121212);
        color: var(--gcc-ink, #e8e8e8);
    }
    body.gcc-sb-open .gcc-sb-launch { display: none; }

    .gcc-sb-veil {
        position: fixed; inset: 0; z-index: 59;
        background: rgba(0, 0, 0, .45);
        opacity: 0; pointer-events: none;
        transition: opacity .2s ease;
    }
    body.gcc-sb-open .gcc-sb-veil { opacity: 1; pointer-events: auto; }

    /* The header's own buttons sit beside the launcher rather than under it. */
    /* The room the button occupies: its own 40px plus a 10px gap. It was 48,
       which is the button alone and half a gap. */
    /* THE HOME PAGE makes room BESIDE the brand: the launcher and the brand share
       a row, which is what was asked for. */
    body.gcc-sb-mobile-only header.top { padding-left: 50px; }

    /* THE SUB-PAGES make room ABOVE. They do not all have a header row — a
       pricing page opens on its own heading — so a left indent would push the
       first line sideways on some pages and nothing on others, and on /pricing
       the arrow simply landed on the word. Measured: the arrow occupies 33 to 73
       from the top, so the page begins at 76. Consistent everywhere, and it
       leaves the arrow alone in its corner where a way out belongs. */
    body.gcc-sb-desktop-only .wrap { padding-top: 76px; }

    /* AND THE LAUNCHER GOES WHERE THE DRAWER GOES. The sub-pages hide the rail
       on a phone — they are one task with a way back — so a button offering to
       open it there would open nothing anybody asked for. */
    body.gcc-sb-desktop-only .gcc-sb-launch,
    body.gcc-sb-desktop-only .gcc-sb-veil { display: none; }

    /* AND IN ITS PLACE, THE WAY BACK. The same box in the same spot: on the home
       page that control opens the menu, on every other page it leaves. Sharing
       the rule rather than copying it is what keeps them the same size and the
       same distance from the brand a year from now. */
    .gcc-sb-back { display: none; }
    body.gcc-sb-desktop-only .gcc-sb-back { display: grid; }
    body.gcc-sb-mobile-only .gcc-sb-back { display: none; }

    /* ── AND NOT WHERE THERE IS ALREADY ONE ────────────────────────────────
       `/create` has its own way out: the arrow in the mobile studio's header,
       added when its drawer was removed. This one appeared beside it and landed
       on the card — two exits, one of them in the way of the work.

       `body.gcc-ms` is the right test rather than the page's address, because it
       says the thing that matters: this screen brings its OWN chrome, so it does
       not want the chrome that pages without any are given.

       The pages that keep it, and why, surveyed rather than assumed:
         /pricing, /thanks, /feedback  a link in the footer of a long page, which
                                       is a thing to scroll to, not a way out
         /account                      a link to home only in its SIGNED-OUT
                                       state; signed in there was none at all
         /my-cards                     the brand in its header links home, which
                                       works but is not a way out anybody looks
                                       for; it keeps the arrow for consistency
                                       and they do not overlap
         /create                       has one — excluded here */
    body.gcc-ms .gcc-sb-back { display: none; }

    /* The top reserve goes with it: the studio lays out its own screen and does
       not use `.wrap`, but saying so costs nothing and stops the next page that
       does from inheriting a gap it has no arrow to make room for. */
    body.gcc-ms .wrap { padding-top: 20px; }
}

/* ── THE PHONE'S OWN CHROME DOES NOT BELONG ON A DESKTOP ─────────────────
   The launcher, its veil and the way back are all built inside the
   `max-width: 900px` block above — position, size, border, the lot. Above 900
   they therefore have no rules at all, and an element with no rules is not
   hidden: it is an ordinary inline link at the top of the document.

   Which is what was reported, with a screenshot — a bare `<` in the corner of
   the desktop home page. The launcher and the veil were named here from the
   day this was written; the arrow was added later and was not, and the two
   lines were never the same list. They are now. */
@media (min-width: 901px) {
    .gcc-sb-launch,
    .gcc-sb-veil,
    .gcc-sb-back { display: none; }
}

@media (min-width: 901px) {
    body.gcc-sb-mobile-only .gcc-sidebar { display: none; }
    body.gcc-sb-mobile-only .gcc-page-wrap { padding-left: 0; }
}

.gcc-sb-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 4px 6px 10px;
}

.gcc-sb-brand {
    display: flex;
    align-items: center;
    gap: 9px;
    color: inherit;
    text-decoration: none;
    font-weight: 700;
    letter-spacing: .2px;
    white-space: nowrap;
}

.gcc-sb-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    border: 0;
    border-radius: 7px;
    background: none;
    color: inherit;
    cursor: pointer;
}

.gcc-sb-toggle:hover { background: rgba(127, 127, 127, .18); }

.gcc-sb-nav { display: flex; flex-direction: column; gap: 2px; }

/* Push the account section to the foot */
.gcc-sb-foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-top: 8px;
    border-top: 1px solid rgba(127, 127, 127, .16);
}

.gcc-sb-item,
.gcc-sb-user {
    display: flex;
    align-items: center;
    gap: 10px;
    /* A 34px square when collapsed: the icon has to stay exactly where it is as the
       rail opens and closes, or the eye loses the selected item. */
    min-height: 34px;
    padding: 7px 8px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.gcc-sb-item svg,
.gcc-sb-avatar { flex: 0 0 auto; }

/* `@media (hover: hover)`, for the reason every other hover rule in this
   codebase carries it: a touchscreen has no hover, so the browser invents one on
   tap and then LEAVES IT THERE. Without this, the last sidebar item somebody
   touched stays highlighted, and on a phone that reads as the page you are on. */
@media (hover: hover) {
    .gcc-sb-item:hover { background: rgba(127, 127, 127, .18); }
}

/* THE ONE ITEM ON THIS RAIL WITH A COLOUR.
   It sits below Sign out, outside the navigation, and nothing about using this
   product requires it — so it must not compete with the items that do. What it
   gets instead of position is a single red heart: at the foot of a grey column
   that is noticed once, which is the right number of times. The LABEL stays the
   same colour as everything else, because a whole red row would read as a
   warning. */
.gcc-sb-thanks {
    /* Air above it, so it reads as a separate thing rather than as the last
       row of the account cluster it happens to sit under. */
    margin-top: 10px;

    /* A HAIRLINE AND A TINT, NOT A FILLED BUTTON.
       Every other row on this rail is transparent until the pointer is over it.
       This one carries its own outline permanently, which is what makes it look
       placed rather than left over — and it is the whole of the formality. A
       solid red button here would be louder than "Create card", and an item
       nobody needs must never out-shout the one everybody does.

       Both colours are the heart's own, at low alpha, so the box is theme-proof:
       over a pale ground it settles to a soft blush, over a dark one to a faint
       warmth, and neither had to be written twice. */
    border: 1px solid rgba(239, 75, 98, .28);
    background: rgba(239, 75, 98, .07);
}

/* The heart itself, and the only colour on the rail. */
.gcc-sb-thanks svg { color: #ef4b62; }

@media (hover: hover) {
    /* Its own hover, or the grey one above would wash the tint out and the box
       would appear to lose its colour exactly when it is being pointed at. */
    .gcc-sb-thanks:hover {
        border-color: rgba(239, 75, 98, .55);
        background: rgba(239, 75, 98, .13);
    }
}

/* Nothing here for the collapsed rail. `.gcc-sb-thanks` also carries
   `.gcc-sb-item`, so the rules that centre and unpad every item when the rail
   narrows already reach it — and the border simply follows the narrower box.
   The first draft of this added its own `justify-content: center`, which is
   only ever wanted when the rail is CLOSED and centred the row while it was
   open. */

.gcc-sb-item.is-active {
    background: rgba(127, 127, 127, .26);
    font-weight: 600;
}

.gcc-sb-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #2f6bff;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}

.gcc-sb-email {
    overflow: hidden;
    text-overflow: ellipsis;
    opacity: .7;
    font-size: 12px;
}

.gcc-sb-user { cursor: default; }

/* Collapsed to a rail: hide the text, keep the icon. display:none and not opacity
   — text hidden by opacity still takes space and still takes the mouse. */
body.gcc-sb-collapsed .gcc-sb-text { display: none; }
body.gcc-sb-collapsed .gcc-sb-head { justify-content: center; padding-inline: 0; }
body.gcc-sb-collapsed .gcc-sb-brand { display: none; }
body.gcc-sb-collapsed .gcc-sb-item,
body.gcc-sb-collapsed .gcc-sb-user { justify-content: center; padding-inline: 0; }

/* Narrow sizes: the rail collapses itself. 232px on a phone eats over half the
   workspace width. */
@media (max-width: 900px) {
    :root { --gcc-sb-w: 52px; }
    .gcc-sidebar .gcc-sb-text { display: none; }
    .gcc-sidebar .gcc-sb-brand { display: none; }
    .gcc-sb-head { justify-content: center; padding-inline: 0; }
    .gcc-sb-item, .gcc-sb-user { justify-content: center; padding-inline: 0; }
}

/* TWO COLUMNS: the workspace on the left, the preview on the right.
   It was once one column with the preview in the middle; the working part was then
   pushed below the fold, so typing and watching at once was awkward. Two columns
   keep both in view together. */
/* The page shell: the full screen width.
   The old version clamped it to 1200px + 24px of padding in an inline <style> block
   in create.html — which comes AFTER the <link>, so at equal specificity it won and
   overriding here was useless. That inline rule was deleted outright rather than escalated against.
   The composing page is a two-column workspace, not an article: clamp the width and
   the preview band stops halfway, leaving two empty strips at the sides. */
.gcc-page-wrap {
    max-width: none;
    margin: 0;
    padding-inline: 0;
}

.gcc-two-col {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    /* No gap between the columns: split in two, the boundary is ONE line; a gap turns
       it into two and the compose box can never reach the edge. */
    gap: 0;
    /* The full screen width. Zero horizontal margin so the right column's ground
       reaches the right edge with no gap. The left column keeps a 640px ceiling and
       centres itself, so the text is not stretched into unreadable lines. */
    max-width: none;
    margin: 0;
    /* Zero margin on all four sides: the right-hand ground has to reach all four
       edges, with no thin black strip above or below. All the breathing room moves to the left column. */
    padding: 0;
}

.gcc-two-col > .gcc-col--form {
    order: 1;
    flex: 1 1 auto;
    min-width: 0;
    /* The left column is the screen height so the compose box PINS TO THE FOOT.
       Without a height the column is only as tall as its content, and while the
       conversation is short the compose box floats in the middle of the page. */
    display: flex;
    flex-direction: column;
    height: 100vh;
    min-height: 420px;
    padding-block: 16px 24px;
    /* It fills the left half — the compose box runs right up to the boundary with the
       preview, with no empty band between. The old 640px ceiling pulled the box to the
       middle of the left half and made it look abandoned in a black field.
       The ceiling only returns when the preview is COLLAPSED (see the rule below): the
       column then takes the whole screen, and a line past 80 characters is tiring to read. */
    flex: 0 0 50%;
    max-width: 50%;
    margin-inline: 0;
    padding-inline: 24px;
    box-sizing: border-box;
}

/* Preview collapsed: with no right column to share with, the width ceiling and
   centring return, or the compose box stretches across the whole screen. */
.gcc-two-col.gcc-pv-collapsed > .gcc-col--form {
    flex: 1 1 auto;
    max-width: 820px;
    margin-inline: auto;
}

.gcc-two-col > .gcc-col--preview {
    order: 2;
    /* An exact 50:50 split. No width ceiling: a ceiling makes the right column
       narrower than half the screen on a large display and the ratio is off at once.
       The card inside has a ceiling of its own, so extra width does not bloat it. */
    flex: 0 0 50%;
    max-width: 50%;
    /* Sticky: scroll a long conversation and the card stays in view */
    position: sticky;
    top: 16px;
    /* Its own ground, to separate the two areas: the left is where the work happens,
       the right is where the result is seen. They used to share one ground, so the card
       looked adrift in the middle of the page with no clear boundary.
       A translucent grey rather than a fixed colour — right in both light and dark
       themes by itself. */
    /* 0.07 is too faint: over #0d0d0d it gives #1a1a1a — a difference of 7/255, and
       the eye does not read it as a separate area. 0.22 gives about #262626, clearly
       distinct without glaring. */
    background: rgba(127, 127, 127, .22);
    /* NO rounded corners, NO border: the ground has to be THE WHOLE COLUMN, a band
       running the full screen height — not a framed box floating in the column. As tall
       as the left column, so the two areas meet along one straight vertical line. */
    border: 0;
    border-radius: 0;
    height: 100vh;
    min-height: 420px;
    /* Zero horizontal padding: the control bar has to touch the very top of the
       ground, or scrolling content shows through the gap above it. The padding moves
       down to the individual children. */
    padding: 0;
    overflow-y: auto;
}

/* The control bar PINS TO THE TOP of the preview — the column scrolls, the bar stays.
   backdrop-filter rather than an opaque ground: the column ground is a translucent
   grey, so another translucent layer over it still sees through, and the card
   scrolling up shows faintly behind the word PREVIEW. */
.gcc-two-col > .gcc-col--preview > .gcc-pv-bar {
    position: sticky;
    top: 0;
    z-index: 3;
    /* border-box is REQUIRED: the .gcc-col--preview > * rule sets width:100%, and the
       default content-box makes that 100% PLUS the padding — the bar overflowed the
       column by 18px on each side and PREVIEW ended up flush to the edge. Measured:
       the column 451 wide and the bar 487. */
    box-sizing: border-box;
    padding: 14px 18px;
    background: rgba(127, 127, 127, .16);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

/* The horizontal padding is given back to the rest (the column dropped it to pin the bar). */
.gcc-two-col > .gcc-col--preview > *:not(.gcc-pv-bar) {
    box-sizing: border-box;
    padding-inline: 18px;
}

/* The card is centred VERTICALLY in what is left of the column.
   It used to stick just below the control bar with 267px empty beneath — measured:
   a column 918 tall, a bar of 51 and a card of 600. The body now takes all the spare
   space and centres itself, while leaving room so the Presets chip does not touch
   the bar's grey band. */
.gcc-two-col > .gcc-col--preview > .gcc-preview-toggle {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: 14px 18px;
}

.gcc-two-col > .gcc-col--preview > *:last-child { padding-bottom: 14px; }

/* Preview collapsed: the right column disappears and the workspace takes it all. */
.gcc-two-col.gcc-pv-collapsed > .gcc-col--preview { display: none; }

/* Full screen */
.gcc-col--preview.gcc-pv-full {
    position: fixed;
    inset: 0;
    z-index: 200;
    max-width: none;
    flex: none;
    margin: 0;
    padding: 56px 20px 24px;
    background: var(--bg, #0d0d0d);
    border: 0;
    border-radius: 0;
    overflow: auto;
    justify-content: center;
}

/* The scrollbar is hidden in the preview — the scrolling itself REMAINS.
   At full screen a grey strip down the right edge cut across the card and destroyed
   any sense of looking at a finished thing. Applied in both the normal and the
   full-screen state, since the right column scrolls too when the card is taller than the screen. */
.gcc-col--preview,
.gcc-col--preview.gcc-pv-full,
.gcc-preview-toggle__panel {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.gcc-col--preview::-webkit-scrollbar,
.gcc-col--preview.gcc-pv-full::-webkit-scrollbar,
.gcc-preview-toggle__panel::-webkit-scrollbar { width: 0; height: 0; }

@media (max-width: 900px) {
    .gcc-two-col {
        flex-direction: column;
        align-items: center;
        max-width: 520px;
        padding: 12px 12px 24px;
    }
    .gcc-two-col > .gcc-col--preview {
        order: 1;
        flex: none;
        max-width: 100%;
        position: static;
        /* Stacked, the column is no longer a band beside the workspace — a screen height
           would push the working part entirely out of sight below. */
        height: auto;
        min-height: 0;
    }
    .gcc-two-col > .gcc-col--form { max-width: 100%; }
    .gcc-two-col > .gcc-col--form { order: 2; width: 100%; }
}

/* The preview width is separate from the compose box's: the card holds its ratio,
   so wider is taller, while the utility row needs horizontal room for 9 items. */
.gcc-col--preview {
    /* flex to stop margin collapse — the card's top margin used to escape the column,
       making it shorter than its content and covering the compose box. */
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 0 auto;
}

/* The flex column's align-items:center shrinks its children to their CONTENT
   width. The preview wrapper chain has no intrinsic width, so it collapsed to 0 and
   the card was left at 16px. The whole chain takes the full column width. */
.gcc-col--preview > *,
.gcc-preview-toggle,
.gcc-preview-toggle__panel,
.gcc-preview-toggle__panel > .gcc-col--preview {
    width: 100%;
    max-width: 100%;
}

/* The column nested in the panel: the old version's relative offset goes (a
   relative offset does not count towards the parent's height, so the element spilled down over the compose box). */
.gcc-preview-toggle__panel > .gcc-col--preview { position: static; }

.gcc-chat-shell {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    /* NOT var(--ink): see the token note above. gcc-layout-center.js still sets the
       colour inline to get past this exact bug — a correct rule here means that JS
       workaround is no longer the only thing keeping the text readable. */
    color: var(--gcc-pnl-fg);
    font-family: var(--sans, 'Be Vietnam Pro', system-ui, sans-serif);
}

.gcc-screen {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* flex:1 + min-height:0 — the pair required for the inner scrolling to work.
       Without min-height:0 a flex item will not shrink below its content, the
       conversation stretches the column and the compose box leaves the foot again. */
    flex: 1 1 auto;
    min-height: 0;
}

/* The device case: no longer used. Kept in the DOM because other modules still
   query for it, but it draws nothing. */
.gcc-ios-statusbar,
.gcc-iphone-btn,
.gcc-iphone-btn-power,
.gcc-iphone-btn-volup,
.gcc-iphone-btn-voldown,
.gcc-chat-header { display: none; }

/* The home indicator is still a menu button — hidden from the eye, not from the keyboard. */
.gcc-iphone-home-btn {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    opacity: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
 * 2. THE CONVERSATION STREAM
 * ══════════════════════════════════════════════════════════════════════════ */
/* THE ANCHOR BLOCK — the opening line and the input, OUTSIDE the scrolling area.
   `flex: 0 0 auto` is the entire point: it does not shrink, grow or scroll, so the
   input stays at one coordinate throughout the conversation. `.gcc-chat-stream`
   just below is what grows and scrolls. */
.gcc-chat-neo {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    gap: 12px;
    padding: 2px 2px 12px;
}

.gcc-chat-stream {
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* It grows into the space and only then scrolls — this is what pushes the compose box to the foot. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 2px;
    /* The content gathers at the bottom: the newest message always sits against the
       compose box, as in every conversation view. */
    justify-content: flex-end;
    /* The scrollbar is hidden and the scrolling KEPT. The old scrollbar was a grey
       strip beside the card, cutting across the layout. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.gcc-chat-stream::-webkit-scrollbar,
.gcc-chat-input-mwac::-webkit-scrollbar,
.gcc-chat-final-summary::-webkit-scrollbar { width: 0; height: 0; }

.gcc-chat-input-mwac,
.gcc-chat-final-summary { scrollbar-width: none; -ms-overflow-style: none; }

.gcc-chat-bubble {
    font-size: 14px;
    line-height: 1.55;
    max-width: 88%;
}

/* Do NOT use var(--surface) here: it is redefined at a nearer level with a LIGHT
   value (#f7f7f7), so the bubble ground came out nearly white against light text —
   a measured contrast of 1.19. A translucent grey is right on any ground. */

/* The assistant's words: plain text on the page ground. Bubbles on both sides are
   the language of phone messaging; here it is enough to tell who is speaking. */
.gcc-chat-bubble.bot { align-self: flex-start; }

.gcc-chat-bubble.user {
    align-self: flex-end;
    background: rgba(127, 127, 127, .18);
    border-radius: 14px;
    padding: 8px 12px;
}

.gcc-chat-bubble.error {
    align-self: flex-start;
    color: var(--danger, #d92d20);
}

.gcc-chat-edit-hint {
    display: block;
    font-size: 10px;
    opacity: .5;
    margin-top: 2px;
}

.gcc-chat-typing { opacity: .55; font-size: 13px; }

/* The current step's question is already in the compose box → hide the copy in the
   stream (js/gcc-chatbox.js adds this class). */
/* The question SHOWS IN FULL in the stream. The previous version hid the current
   step's bubble because the question was stuffed into the input placeholder; that
   left the pickers (templates, images) with nothing to anchor to — the user saw a
   basket of buttons with no idea what they were answering. */

/* ══════════════════════════════════════════════════════════════════════════
 * 3. THE COMPOSE BOX
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-chat-input-area {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    /* EVEN vertical spacing between every child, and EVEN padding on four sides. The
       previous version used 10/12/8 — three different numbers, so the button row at the
       foot looked stuck to the border while the top edge had room to spare. */
    gap: 12px;
    /* NO BORDER. This block already sits in the compose column body — which has a
       ground and padding of its own — so a frame around it is only one more line inside
       a line, and it eats the width of everything within: the input, the choices, the
       button row. In a narrow column those pixels are the difference between a button
       row fitting on one line and breaking into two. */
    padding: 2px 0 0;
}

.gcc-chat-input-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.gcc-chat-input-row input,
.gcc-chat-input-row textarea,
.gcc-chat-mwac-msg-ta,
.gcc-chat-caption-ta {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 14px;
    line-height: 1.5;
    padding: 2px 0;
    resize: none;
}

.gcc-chat-input-row input:focus,
.gcc-chat-input-row textarea:focus,
.gcc-chat-mwac-msg-ta:focus,
.gcc-chat-caption-ta:focus { outline: none; }

.gcc-chat-input-row input::placeholder,
.gcc-chat-input-row textarea::placeholder { color: inherit; opacity: .5; }

/* The question on a choice step (with no input) */
/* The blinking caret while typing (js/gcc-typewriter.js) — the sign of "writing",
   and an anchor for the eye so new text does not jump in abruptly. */
.gcc-chat-bubble.bot.gcc-tw-running::after {
    content: '';
    display: inline-block;
    width: 2px;
    height: 1em;
    margin-left: 2px;
    vertical-align: -2px;
    background: currentColor;
    opacity: .65;
    animation: gcc-tw-nhay .8s steps(1) infinite;
}

@keyframes gcc-tw-nhay { 0%, 49% { opacity: .65 } 50%, 100% { opacity: 0 } }
.gcc-chat-counter { font-size: 10px; opacity: .45; align-self: flex-end; }
.gcc-chat-actions-row:empty { display: none; }

.gcc-chat-actions-row {
    display: flex;
    gap: 8px;
    /* IT WRAPS WHEN THERE IS NO ROOM, AND EACH ROW FILLS THE WIDTH.
       This is the fourth version of this row; the three before were each wrong in their
       own way, recorded here so nobody repeats them:
         · plain `wrap` — "Start over" dropped down alone, and four buttons of one group
           looked like three plus one.
         · SHRINKING buttons with an ellipsis — a pill has 16px of padding on each side,
           so shrinking the width exhausts the room for text first and the text runs over the border itself.
         · one row + horizontal scroll — evading the problem: the last button is always
           half sliced, and the scrollbar is hidden so nobody knows it scrolls.
       The pair `flex: 1 1 auto` + `min-width: max-content` ON THE BUTTON (declared just
       below) is what solves all three: never narrower than its own text, yet growing to
       fill the spare room on whatever line it is on. A wrapped line then looks like a
       deliberately full row rather than one stray button. */
    flex-wrap: wrap;
    /* It may not be crushed — this row is a flex item of the compose box, and the box
       has `max-height: 72%`. With enough content the box hits its ceiling, and a flex
       item defaults to `flex-shrink: 1`, so the browser squeezes the button row itself
       to fit: the row measured 16px while the buttons inside were still 34px tall, and
       the buttons were sliced top and bottom — looking exactly as if another layer covered them. */
    flex-shrink: 0;
}

.gcc-chat-actions-row::-webkit-scrollbar { height: 0; }

.gcc-chat-actions-row > .gcc-chat-btn {
    /* `1 1 auto` lets it grow, `max-content` forbids shrinking below the text width.
       Without the second, `flex-basis: auto` still lets the browser squeeze a button when
       space is tight — the old bug of "text cut mid-word and still sticking past the edge". */
    flex: 1 1 auto;
    min-width: max-content;
    white-space: nowrap;
}


/* ── Buttons ─────────────────────────────────────────────────────────── */
/* Buttons do NOT use var(--ink-strong)/var(--bg): both are redefined at a nearer
   level with LIGHT-theme values, so on a dark ground they give white text on a light
   ground — a measured contrast of 1.27 on the AI button. Colour pairs written
   explicitly per data-theme depend on no token at all. */
/* ONE mould for every button: the same height, radius and padding. The primary
   used to be 7px/16px and the secondary 5px/10px — side by side they were uneven,
   which is exactly the "messy" feeling. Only COLOUR separates primary from
   secondary, never size. */
.gcc-chat-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 34px;
    box-sizing: border-box;
    border: 1px solid transparent;
    border-radius: 999px;
    background: #1d1d1f;
    color: #ffffff;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 7px 16px;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
}

:root[data-theme="dark"] .gcc-chat-btn,
:root:not([data-theme="light"]) .gcc-chat-btn {
    background: #e8e8e8;
    color: #101010;
}

.gcc-chat-btn:hover { opacity: .88; }

/* The secondary button: an outline style needing no colour pair, so it is right in
   every theme. Placed AFTER the data-theme block above, to beat it. */
.gcc-chat-btn.ghost,
.gcc-chat-btn-icon,
:root[data-theme="dark"] .gcc-chat-btn.ghost,
:root[data-theme="dark"] .gcc-chat-btn-icon,
:root:not([data-theme="light"]) .gcc-chat-btn.ghost,
:root:not([data-theme="light"]) .gcc-chat-btn-icon {
    /* IT HAS A GROUND, not `none`. A `rgba(127,127,127,.35)` border on #121212 is so
       faint that only the two curved ends show — the row reads as a few words with
       brackets adrift on the ground, not as buttons. A pill needs a BODY before the eye
       can find the hit area; an outline alone will not do. */
    background: var(--pf-surface-2, rgba(127, 127, 127, .12));
    color: inherit;
    border: 1px solid var(--pf-line, rgba(127, 127, 127, .55));
    /* The same padding as the primary — only the colour differs, never the size. */
    padding: 7px 16px;
    font-weight: 500;
}

.gcc-chat-btn.ghost:hover,
.gcc-chat-btn-icon:hover { background: rgba(127, 127, 127, .14); }

/* The send button in the input row: a round arrow button, not a block of text.
   It applies to the PRIMARY button ONLY. The old rule swept every .gcc-chat-btn in
   the input row, so when gcc-compose-layout.js moved Skip into that row, Skip was
   squeezed to 30px, font-size:0, and grew an ↑ — giving TWO identical arrow buttons
   side by side. Measured: both 30px wide with the same ::after "↑", one of them
   actually labelled "Skip". */
.gcc-chat-input-row .gcc-chat-btn:not(.secondary):not(.gcc-row-secondary-btn) {
    /* A GENUINE SQUARE. The previous version set only width:30px and forgot the
       shared button mould carries min-height:34px and 7px/16px of padding — giving a
       30×34 oval with the text crushed inside, exactly the visible "distortion".
       All three have to be cancelled: the width, the minimum height and the padding. */
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    min-height: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* A TRANSPARENT ground: the send button sits inside the compose box, where the
       context is already clear, so no solid block is needed to pull the eye off the text being typed.
       The ground appears on hover alone. */
    background: none;
    color: inherit;
    /* Hide the word "Send" — the engine sets the button content as text, while here
       only the icon is wanted. Remove this line and the text returns, pushing the icon
       out of the 30px box (measured: the icon left at 0 width). The text stays in the
       DOM, so a screen reader still reads "Send". */
    font-size: 0;
    line-height: 0;
    transition: background-color .12s ease;
}

/* The arrow is SVG and not the character '↑': an arrow character has a different
   shape in every font, some fonts lack the glyph entirely and the browser substitutes
   an empty box. In SVG every machine draws the same shape.
   It is filled with `background: currentColor` through a mask, so it follows the text
   colour with no separate declaration for light and dark. */
.gcc-chat-input-row .gcc-chat-btn:not(.secondary):not(.gcc-row-secondary-btn)::after {
    content: '';
    width: 17px;
    height: 17px;
    background: currentColor;
    -webkit-mask: var(--gcc-icon-gui) center / contain no-repeat;
    mask: var(--gcc-icon-gui) center / contain no-repeat;
}

.gcc-chat-input-row .gcc-chat-btn:not(.secondary):not(.gcc-row-secondary-btn):hover {
    background: rgba(127, 127, 127, .18);
}

.gcc-chat-input-row .gcc-chat-btn:not(.secondary):not(.gcc-row-secondary-btn):disabled {
    opacity: .35;
    cursor: not-allowed;
}

/* ══════════════════════════════════════════════════════════════════════════
 * 4. CHOICES
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-chat-choices {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gcc-chat-choice {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: center;
    border: 1px solid var(--line, rgba(127, 127, 127, .3));
    border-radius: 12px;
    background: none;
    color: inherit;
    font: inherit;
    padding: 10px 12px;
    cursor: pointer;
}

.gcc-chat-choice:hover { background: rgba(127, 127, 127, .12); }
.gcc-chat-choice-label { font-size: 13px; font-weight: 600; }
.gcc-chat-choice-desc  { font-size: 11px; opacity: .55; }

/* The effect grid: many small cells lay out across, to keep it short */
.gcc-chat-choices.gcc-fx-choices {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
}

.gcc-chat-choices.gcc-fx-choices .gcc-chat-choice { padding: 8px 4px; }
.gcc-chat-choices.gcc-fx-choices .gcc-chat-choice-desc { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
 * 5. THE PICKER STEPS (media, templates)
 * ══════════════════════════════════════════════════════════════════════════ */
/* This block has several separate parts: the selection summary, the button row
   and the confirm panel for clearing. Putting them all on ONE wrapping row mixes
   them together by whatever width is left — exactly the Cancel / Yes, clear / Change
   / Send jumble. Each part gets its OWN ROW. */
.gcc-chat-pick {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
}

.gcc-chat-pick-buttons,
.gcc-chat-pick-confirm-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    /* The action buttons gather on the RIGHT, as in every other dialog on the page. */
    justify-content: flex-end;
}

.gcc-chat-pick-summary {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    min-height: 34px;
}

.gcc-chat-pick-check   { color: var(--ok, #16a34a); }
.gcc-chat-pick-value   { font-weight: 600; }
.gcc-chat-pick-helper,
.gcc-chat-pick-confirm-msg { font-size: 12px; opacity: .6; }

/* The confirm panel before clearing: an area of its own with a ground and a
   border, so it reads as a nested question and not two more buttons in the row. */
.gcc-chat-pick-confirm-clear {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
    border: 1px solid var(--line, rgba(127, 127, 127, .25));
    border-radius: 12px;
    background: rgba(127, 127, 127, .07);
}

/* ══════════════════════════════════════════════════════════════════════════
 * 6. THE GREETING STEP + THE PER-IMAGE CAPTIONS
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-chat-input-mwac { max-height: 320px; overflow-y: auto; }

.gcc-chat-mwac-message-wrap,
.gcc-chat-mwac-captions-wrap,
.gcc-chat-percaption-fields {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.gcc-chat-mwac-label { font-size: 12px; font-weight: 600; opacity: .8; }

.gcc-chat-mwac-caption-toggle { display: flex; flex-direction: column; gap: 2px; }
.gcc-chat-mwac-caption-toggle-row { display: flex; align-items: center; gap: 8px; }
.gcc-chat-mwac-caption-label { font-size: 12px; }
.gcc-chat-mwac-caption-desc  { font-size: 11px; opacity: .5; margin: 0; }

.gcc-chat-caption-row {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    border: 1px solid var(--line, rgba(127, 127, 127, .25));
    border-radius: 10px;
    padding: 8px;
}

.gcc-chat-caption-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; }
.gcc-chat-caption-icon  { font-size: 20px; }
.gcc-chat-caption-info  { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.gcc-chat-caption-label { font-size: 11px; opacity: .6; }

.gcc-chat-ai-inline-row { display: flex; }
.gcc-chat-ai-inline-btn { font-size: 12px; padding: 6px 12px; }

/* ══════════════════════════════════════════════════════════════════════════
 * 7. THE THEME STEP + THE FINAL STEP
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-chat-autotheme-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}

/* The select takes a whole row and the button drops below. Forced onto one line
   the select is squeezed to a stub and a long label is cut. */
.gcc-chat-autotheme-select {
    flex: 1 1 100%;
    min-width: 0;
    min-height: 34px;
    box-sizing: border-box;
    border: 1px solid var(--line, rgba(127, 127, 127, .35));
    border-radius: 10px;
    /* THE COLOURS HAVE TO BE EXPLICIT, ground and text, <option> included.
       `background: none` leaves it to the browser: the Windows dropdown uses the system
       WHITE while the text still inherits the light colour of the dark theme —
       white on white, and nothing is readable.
       color-scheme tells the browser to draw the arrow and the scrollbar of the
       dropdown in the dark key as well. */
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    color-scheme: light dark;
    font: inherit;
    font-size: 13px;
    padding: 7px 12px;
}

.gcc-chat-autotheme-select option {
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
}

:root[data-theme="dark"] .gcc-chat-autotheme-select,
:root:not([data-theme="light"]) .gcc-chat-autotheme-select { color-scheme: dark; }

.gcc-chat-autotheme-status { font-size: 12px; opacity: .6; }

.gcc-chat-final { display: flex; flex-direction: column; gap: 10px; }

.gcc-chat-final-summary {
    max-height: 130px;
    overflow-y: auto;
    font-size: 12px;
    line-height: 1.6;
    border: 1px solid var(--line, rgba(127, 127, 127, .25));
    border-radius: 10px;
    padding: 10px;
}

/* The create button does NOT carry .gcc-chat-btn (see gcc-chat-engine.js, where
   it builds .gcc-chat-final), so it inherits nothing — the browser draws its default
   button: square corners, a system grey ground. The whole set is redeclared here, to
   the primary button's mould, differing only in taking the full width. */
.gcc-chat-final-create {
    display: block;
    width: 100%;
    box-sizing: border-box;
    min-height: 42px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: #1d1d1f;
    color: #ffffff;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    padding: 11px 16px;
    cursor: pointer;
}

:root[data-theme="dark"] .gcc-chat-final-create,
:root:not([data-theme="light"]) .gcc-chat-final-create {
    background: #e8e8e8;
    color: #101010;
}

.gcc-chat-final-create:hover { opacity: .88; }
.gcc-chat-final-create:disabled { opacity: .5; cursor: not-allowed; }

/* ══════════════════════════════════════════════════════════════════════════
 * 8. THE UTILITY ROW (js/gcc-layout-center.js gathers it here)
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-ubar {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: nowrap;
    padding: 10px 4px 0;
    margin-top: 6px;
    /* No rule above it: the compose box directly above already has a border, and one
       more a few pixels away makes two parallel lines. White space is enough to
       separate the two blocks. */
    font-size: 12px;
}

.gcc-ubar-left,
.gcc-ubar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

/* Three wrappers still carry the iPhone status-bar layout (justified to both ends,
   full width). Here they are only a cluster of chips. */
.gcc-ubar .gcc-ios-time,
.gcc-ubar .gcc-ios-icons,
.gcc-ubar .gcc-ios-island-badge {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
}

.gcc-ios-chip { display: inline-flex; align-items: center; gap: 4px; }

.gcc-ios-plan {
    background: var(--ink-strong, #1d1d1f);
    color: var(--bg, #fff);
    border-radius: 999px;
    padding: 2px 9px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .4px;
}

.gcc-ios-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--accent, #2f6fed);
    color: #fff;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
}

/* The save dot leads the row and stands apart — the only thing that changes colour
   by itself, and it needs a fixed place for the eye to find. */
.gcc-ubar .gcc-ios-time { position: relative; }
.gcc-ios-dot { width: 7px; height: 7px; border-radius: 50%; order: -1; flex: none; }

.gcc-chat-progress {
    border: 1px solid var(--line, rgba(127, 127, 127, .3));
    border-radius: 999px;
    padding: 3px 10px;
    font-size: 11px;
    white-space: nowrap;
}

/* The ↺ and ← buttons lose their borders: in a row that already holds rounded
   chips and a bordered counter, two more frames are clutter. A ground on hover says enough.
   The data-theme variants have to be listed TOO: the secondary-button block in
   section 3 has a `:root[data-theme="dark"] .gcc-chat-btn.ghost` branch (0,4,0),
   more specific than `.gcc-ubar .gcc-chat-btn.ghost` (0,2,0), so the border stayed 1px. */
.gcc-ubar .gcc-chat-btn-icon,
.gcc-ubar .gcc-chat-btn.ghost,
:root[data-theme="dark"] .gcc-ubar .gcc-chat-btn-icon,
:root[data-theme="dark"] .gcc-ubar .gcc-chat-btn.ghost,
:root:not([data-theme="light"]) .gcc-ubar .gcc-chat-btn-icon,
:root:not([data-theme="light"]) .gcc-ubar .gcc-chat-btn.ghost {
    border: 0;
    padding: 4px 7px;
    font-size: 13px;
    line-height: 1.4;
    border-radius: 8px;
}

/* ══════════════════════════════════════════════════════════════════════════
 * 9. THE QUOTA PANEL + THE ACCOUNT MENU
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-plan-pop {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 0;
    z-index: 40;
    width: 232px;
    max-width: calc(100vw - 32px);
    padding: 12px 13px 10px;
    border-radius: 14px;
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    border: 1px solid var(--gcc-pnl-line);
    font-size: 11px;
    opacity: 0;
    pointer-events: none;
    transition: opacity .16s ease;
}

.gcc-plan-pop.is-open { opacity: 1; pointer-events: auto; }

.gcc-plan-pop-head { display: flex; justify-content: space-between; margin-bottom: 8px; }
.gcc-plan-pop-plan { font-weight: 700; }
.gcc-plan-pop-tag  { opacity: .5; text-transform: uppercase; font-size: 9px; }
.gcc-plan-pop-row + .gcc-plan-pop-row { margin-top: 8px; }
.gcc-plan-pop-line { display: flex; justify-content: space-between; }
.gcc-plan-pop-label { opacity: .7; }
.gcc-plan-pop-num  { font-weight: 600; }
.gcc-plan-pop-sep  { opacity: .45; margin: 0 1px; font-weight: 400; }
.gcc-plan-pop-track { height: 3px; border-radius: 2px; background: rgba(127, 127, 127, .3); margin-top: 4px; }
.gcc-plan-pop-fill  { display: block; height: 100%; border-radius: 2px; }
.gcc-plan-pop-ok.gcc-plan-pop-fill   { background: #30d158; }
.gcc-plan-pop-warn.gcc-plan-pop-fill { background: #ff9f0a; }
.gcc-plan-pop-full.gcc-plan-pop-fill { background: #ff453a; }
span.gcc-plan-pop-ok   { color: #30d158; }
span.gcc-plan-pop-warn { color: #ff9f0a; }
span.gcc-plan-pop-full { color: #ff453a; }
.gcc-plan-pop-extra { margin-top: 9px; padding-top: 8px; border-top: 1px solid rgba(127, 127, 127, .25); }
.gcc-plan-pop-sub   { font-size: 9.5px; text-transform: uppercase; letter-spacing: .5px; opacity: .5; margin-bottom: 5px; }
.gcc-plan-pop-grid  { display: grid; grid-template-columns: 1fr auto; gap: 3px 10px; }
.gcc-plan-pop-gk    { opacity: .7; }
.gcc-plan-pop-gv    { font-weight: 600; font-variant-numeric: tabular-nums; }
.gcc-plan-pop-notes { margin-top: 8px; padding-top: 7px; border-top: 1px solid rgba(127, 127, 127, .25); font-size: 10px; opacity: .75; }
.gcc-plan-pop-foot  { margin-top: 7px; font-size: 9.5px; opacity: .45; }
.gcc-plan-pop-empty { opacity: .6; }

/* Anchored to the UTILITY ROW (gcc-layout-center.js moves it there on opening),
   not to the chat frame: that frame is a whole column tall, so `bottom: 100%` pushes
   the slide-out above the top of the column and off the screen. */
.gcc-iphone-navsheet {
    position: absolute;
    right: 0;
    bottom: calc(100% + 8px);
    z-index: 45;
    width: min(240px, 90%);
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px;
    border-radius: 12px;
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    border: 1px solid var(--gcc-pnl-line);
    opacity: 0;
    transform: translateY(6px);
    pointer-events: none;
    transition: opacity .16s ease, transform .16s ease;
}

.gcc-iphone-navsheet.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.gcc-iphone-navsheet-grabber { display: none; }
.gcc-iphone-navsheet-title { font-size: 10px; text-transform: uppercase; letter-spacing: .5px; opacity: .5; padding: 4px 8px; }

.gcc-iphone-navsheet-item,
.gcc-iphone-navsheet-signout {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 13px;
    text-decoration: none;
    cursor: pointer;
    text-align: left;
}

.gcc-iphone-navsheet-item:hover,
.gcc-iphone-navsheet-signout:hover { background: rgba(127, 127, 127, .14); }

/* ══════════════════════════════════════════════════════════════════════════
 * 10. THE RESET CONFIRMATION BOX
 * ══════════════════════════════════════════════════════════════════════════ */
/* The confirm box MUST be hidden while closed. Without this rule it sits at the
   top of the page as two small buttons floating above the preview — exactly what
   looks like "two spare buttons". The engine only adds and removes
   gcc-confirm--visible; the hiding is the CSS's job. */
.gcc-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .45);
    /* THE TRANSITION IS REQUIRED, not decoration.
       The engine (gcc-chat-engine.js, showResetConfirm) sets display:flex with an INLINE
       style on opening, and on closing removes only the class and waits for
       'transitionend' before removing display. With no transition declared that event
       never fires: the inline display:flex stays forever, the scrim covers the page and
       the box hangs there even after OK. */
    opacity: 0;
    transition: opacity .18s ease;
}

.gcc-confirm-backdrop.gcc-confirm--visible { display: flex; opacity: 1; }

/* A safety net: a 0-second transition (with "reduce motion" on, or in some
   browser build) also fails to fire transitionend. display:flex then stays stuck —
   but the scrim stops taking the mouse, so the user is not locked out of the page. */
.gcc-confirm-backdrop:not(.gcc-confirm--visible) { pointer-events: none; }

.gcc-confirm-dialog {
    width: min(320px, calc(100vw - 40px));
    padding: 18px;
    border-radius: 14px;
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    border: 1px solid var(--gcc-pnl-line);
}

.gcc-confirm-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
.gcc-confirm-title   { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.gcc-confirm-message { font-size: 13px; opacity: .75; }

/* ══════════════════════════════════════════════════════════════════════════
 * 11. NARROW SCREENS
 * ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 600px) {
    .gcc-two-col { padding: 8px 12px 20px; }
    .gcc-chat-stream { max-height: 150px; }
    .gcc-ubar { gap: 7px; font-size: 11px; }
    .gcc-ubar-left, .gcc-ubar-right { gap: 6px; }
    .gcc-chat-choices.gcc-fx-choices { grid-template-columns: repeat(3, 1fr); }
}

/* ══════════════════════════════════════════════════════════════════════════
 * 12. THE PICKERS EMBEDDED IN THE COMPOSE BOX
 * The media and template pickers have CSS of their own, written for a LIGHT ground.
 * Their cells carry a light ground, so text inside reads (measured: 16.25), but the
 * text OUTSIDE a cell — titles, breadcrumbs — falls straight onto the dark page: measured 1.12.
 * Those parts inherit the page's text colour.
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-chat-input-area .gcc-modal-title,
.gcc-chat-input-area .gcc-breadcrumb-item,
.gcc-chat-input-area .gcc-section-divider,
.gcc-chat-input-area .gcc-empty-state {
    color: inherit;
}

.gcc-chat-input-area .gcc-modal-title { font-size: 13px; font-weight: 600; }

/* The AI button shares the .gac-trigger class with gac.css, which forces
   `color: var(--gcc-ink-inverse) !important` — that variable resolves to WHITE while
   the button's ground is light: a measured contrast of 1.27.
   This is the ONLY place in this file that needs !important, because it has to beat
   an existing one; a more specific selector (0,2,0 against 0,1,0) does the rest. */
.gcc-chat-input-area .gac-trigger {
    background: #1d1d1f !important;
    color: #ffffff !important;
}

:root[data-theme="dark"] .gcc-chat-input-area .gac-trigger,
:root:not([data-theme="light"]) .gcc-chat-input-area .gac-trigger {
    background: #e8e8e8 !important;
    color: #101010 !important;
}

/* The embedded media picker: its own CSS is written for a LIGHT ground. The
   category chips and media cells carry a light ground and still read (measured: 15),
   but the search box and the titles sit directly on the dark ground — measured 2.81 and 1.54.
   They inherit the page's text colour. */
.gcc-chat-input-area .gcc-mp-title,
.gcc-chat-input-area .gcc-mp-search,
.gcc-chat-input-area .gcc-mp-empty,
.gcc-chat-input-area .gcc-mp-count,
.gcc-chat-input-area .gcc-mp-hint {
    color: inherit;
}

.gcc-chat-input-area .gcc-mp-search::placeholder { color: inherit; opacity: .5; }

/* The media picker uses a whole light-theme TOKEN SCALE (gcc-tokens.css) and
   forces it with !important. Rather than racing specificity rule by rule, only the
   token VALUES are changed at the picker: the original rules run untouched, and only
   the result differs.

   THE WHOLE FAMILY HAS TO FLIP, not one here and there. The first attempt changed
   only --gcc-ink to a light colour and left --gcc-ink-inverse = #ffffff; the Select
   button uses the pair `background: var(--gcc-ink)` + `color: var(--gcc-ink-inverse)`
   and became white text on a light ground — measured 1.23, and the button vanished.
   Change one half of a colour pair and the other half always breaks. */
:root[data-theme="dark"] .gcc-chat-input-area .gcc-mp-box--inline,
:root:not([data-theme="light"]) .gcc-chat-input-area .gcc-mp-box--inline {
    --gcc-ink-strong:        #f4f4f4;
    --gcc-ink:               #e8e8e8;
    --gcc-ink-secondary:     #d0d0d0;
    --gcc-ink-muted:         #b0b0b0;
    --gcc-ink-faint:         #949494;
    --gcc-ink-ghost:         #6f6f6f;
    --gcc-ink-inverse:       #101010;
    --gcc-ink-inverse-muted: #3a3a3a;

    --gcc-ink-strong-hover:    #ffffff;
    --gcc-ink-hover:           #f4f4f4;
    --gcc-ink-secondary-hover: #e0e0e0;
    --gcc-ink-muted-hover:     #c4c4c4;
    --gcc-ink-inverse-hover:   #000000;

    /* The surface tokens have to be OPAQUE, never translucent.
       Some rules use them as a TEXT COLOUR over an ink ground — the Select button is
       `background: var(--gcc-ink)` + `color: var(--gcc-surface)`. Made translucent, the
       text disappears: the computed colour measured rgba(127,127,127,0.06).
       An opaque grey scale works both as a ground on a dark page and with enough
       contrast when used as text on a light one. */
    --gcc-surface:        #0f0f0f;
    --gcc-surface-1:      #171717;
    --gcc-surface-2:      #1d1d1d;
    --gcc-surface-3:      #232323;
    --gcc-surface-4:      #2a2a2a;
    --gcc-surface-raised: #1d1d1d;
    --gcc-surface-sunken: #141414;

    --gcc-line: rgba(127, 127, 127, .30);
}

/* ══════════════════════════════════════════════════════════════════════════
 * 13. THE PREVIEW CONTROL BAR (js/gcc-workspace.js)
 * ══════════════════════════════════════════════════════════════════════════ */
.gcc-pv-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 0 2px 8px;
}

/* The control bar inherited #333 text from the old chat frame (hard-coded because
   the old version always sat on a white "phone screen"). The preview ground has just
   lightened to #262626, leaving #333 at about 1.1 contrast — the text disappears. The
   colour is set outright here, as a light/dark pair, rather than borrowing somebody else's token. */
.gcc-pv-bar { color: #1a1a1a; }

:root[data-theme="dark"] .gcc-pv-bar,
:root:not([data-theme="light"]) .gcc-pv-bar { color: #e4e4e4; }

.gcc-pv-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .3px;
    text-transform: uppercase;
    opacity: .65;
}

.gcc-pv-actions { display: flex; gap: 6px; }

.gcc-pv-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
    border: 1px solid rgba(127, 127, 127, .3);
    border-radius: 8px;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.gcc-pv-btn:hover { background: rgba(127, 127, 127, .14); }

/* The `hidden` attribute MUST work here.
   The `display: inline-flex` rule just above is (0,1,0), while the browser's
   `[hidden] { display: none }` is also (0,1,0) but in the default sheet — and a
   page's sheet always beats the default. So setting `nut.hidden = true` in JS puts
   the attribute on the element and the button still shows.
   Measured exactly so: hidden=true with a non-null offsetParent, and the Card size
   button still on the wedding card's toolbar. */
.gcc-pv-btn[hidden] { display: none; }

/* The Preview button lives in the UTILITY ROW, at the far right — on the same row
   as the other tools rather than floating above the compose box.
   It has to belong to the LEFT column: the right column is display:none while
   collapsed, so a button placed there would vanish with it and there would be no way to reopen. */
.gcc-ubar .gcc-pv-reopen {
    margin: 0;
    padding: 4px 9px;
    border-radius: 999px;
    font-size: 12px;
}

.gcc-ubar .gcc-pv-reopen span { font-size: 12px; }

/* Full screen: the card grows as far as allowed while keeping its ratio. */
.gcc-col--preview.gcc-pv-full .gcc-pv-bar {
    position: sticky;
    top: 0;
    padding: 10px 2px;
    background: var(--bg, #0d0d0d);
    z-index: 2;
}

.gcc-col--preview.gcc-pv-full .gcc-preview-card,
.gcc-col--preview.gcc-pv-full .gcc-preview-wedding-card {
    max-width: min(520px, 92vw);
    margin: 0 auto;
}


/* ══════════════════════════════════════════════════════════════════════════
 * 14. THE ENGINE'S STATE CLASSES
 * ══════════════════════════════════════════════════════════════════════════
 * gcc-chat-engine.js toggles the 10 classes below to change the interface state,
 * but NO loaded CSS file defines them — they lived in the old CSS that was
 * deleted. The worst consequence is `gcc-hidden`: the engine "hides" the old button
 * row and opens the confirm panel, and both show, one over the other — exactly the
 * Cancel / Yes, clear / Change / Send jumble.
 * Compiled by scanning every addClass/removeClass/toggleClass in the engine and
 * comparing against the loaded CSS, so this list is complete rather than guessed. */

/* .gcc-hidden twice, for a specificity of 0,2,0 — beating the display:flex rules
   above without !important. */
.gcc-hidden.gcc-hidden { display: none; }

/* The character counter: near the limit / over it. */
.gcc-chat-counter.gcc-near { color: #e0a800; opacity: .95; }
.gcc-chat-counter.gcc-over { color: #e05c50; opacity: 1; font-weight: 600; }

/* A repeated error bubble: a small shake saying "that happened again" — without
   this rule a second failed Send looks like no response at all. */
.gcc-shake { animation: gcc-shake .4s ease; }

@keyframes gcc-shake {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-5px); }
    40%      { transform: translateX(5px); }
    60%      { transform: translateX(-3px); }
    80%      { transform: translateX(3px); }
}

/* The per-image caption area when the caption switch is off. */
.gcc-mwac-disabled {
    opacity: .45;
    pointer-events: none;
}

/* The selected choice (on a choice step) and the state of a pick step. */
.gcc-chat-choice.selected {
    border-color: currentColor;
    background: rgba(127, 127, 127, .16);
}

.gcc-chat-pick.is-picking { opacity: .6; pointer-events: none; }
.gcc-chat-pick.is-empty .gcc-chat-pick-check { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
 * 15. NO TRADITIONAL SCROLLBARS — ACROSS THE PAGE
 * ══════════════════════════════════════════════════════════════════════════
 * They used to be hidden only in the stream and the preview, so a grey bar still
 * appeared in the image picker, the caption area, the quota panel… Set once for the
 * whole page. The scrolling REMAINS — only the bar is hidden, and overflow is untouched. */
html,
body,
.gcc-creator-wrap,
.gcc-creator-wrap * {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar,
.gcc-creator-wrap::-webkit-scrollbar,
.gcc-creator-wrap *::-webkit-scrollbar { width: 0; height: 0; }


/* ══════════════════════════════════════════════════════════════════════════
 * 16. THE SPACING RHYTHM IN THE COMPOSE BOX — EACH STEP'S WRAPPER
 * ══════════════════════════════════════════════════════════════════════════
 * The compose box has `gap: 12px`, but gap applies to DIRECT children ONLY. The
 * engine wraps several rows in a wrapper ($box) and drops that into the box — and
 * inside the wrapper there is no spacing left.
 * Measured on the theme step: the "Apply Theme" button ended at y=795 and "No
 * thanks" began at exactly y=795 — flush together, because they sit in two
 * different sub-wrappers of .gcc-chat-autotheme (display:block).
 * The wrappers the engine builds are listed explicitly rather than swept with
 * `> *`: a sweep would force blocks that need a horizontal layout into columns. */
.gcc-chat-autotheme,
.gcc-chat-final,
.gcc-chat-percaption,
.gcc-chat-ai-suggest {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* EVERY button row gathers right — the same convention as the reset confirm box.
   Some left and some right is precisely what reads as inconsistency. */
.gcc-chat-actions-row,
.gcc-chat-autotheme-row,
.gcc-chat-pick-buttons,
.gcc-chat-pick-confirm-buttons,
.gcc-chat-ai-inline-row {
    justify-content: flex-end;
}

/* BUT A BUTTON ROW THAT MAY OVERFLOW HAS TO ALIGN "SAFE".
   `flex-end` with overflowing content pushes the excess to the LEFT EDGE — and the
   left is the side that CANNOT be scrolled to: `overflow-x: auto` only scrolls
   overflow on the right. Measured: five buttons in a 393px column gave negative
   `offsetLeft` (-192, -66) while `scrollWidth` still equalled `clientWidth` — the
   browser does not count it as scrollable, and it is clipped for good. The user saw
   exactly the tail "…work" of one button, with the primary one gone entirely.
   The `safe` keyword exists for exactly this: with room it aligns right by the
   shared convention, and on overflow it falls back to the left so nothing is clipped. */
.gcc-chat-actions-row,
/* AND THE THEME ROW, for the same reason and found the same way. Measured in the
   mobile sheet: "No thanks, I'll pick manually" is 207px of button, and in a
   narrow sheet plain `flex-end` pushed 45px of it off the LEFT edge — the side
   `overflow-x` cannot scroll to. It is only reached below about 220px today, but
   the width that matters is not the screen's: a phone set to large text, or a
   longer wording, moves that button past any sheet. */
.gcc-chat-autotheme-row {
    justify-content: safe flex-end;
}

/* The select keeps its own full row; the right alignment applies only to the buttons below. */
.gcc-chat-autotheme-row > .gcc-chat-autotheme-select { flex: 1 1 100%; }

/* AND NO BUTTON HERE MAY BE WIDER THAN THE SHEET IT IS IN.
   `safe flex-end` above moves an overflowing row's excess to the right, where it
   can at least be scrolled to in a row that scrolls. This one does not scroll,
   it WRAPS — so the honest answer for a button too wide for its sheet is to let
   its own label wrap rather than to choose which edge clips it.
   Measured at 174px: "No thanks, I'll pick manually" is 207px on one line and
   45px of it was cut off. Nothing changes above about 220px, where it fits on
   one line and this rule never applies. */
.gcc-chat-autotheme-row .gcc-chat-btn {
    max-width: 100%;
    white-space: normal;
}

/* The gap between buttons in one row — smaller than the gap between blocks, so
   the eye reads them as one group. */
.gcc-chat-actions-row,
.gcc-chat-ai-inline-row {
    display: flex;
    gap: 8px;
    align-items: center;
}

/* `flex-wrap` is NOT declared in the combined rule above. That rule comes AFTER
   `.gcc-chat-actions-row` at the top of the file at equal specificity, so it quietly
   overrode `nowrap` with `wrap` — measured: a row of four buttons in a 300px column
   still broke onto two lines despite the earlier `nowrap`. Two rules for one selector
   in one file is the trap: you fix this one and think you are done, while the other
   is the one running.
   The inline AI button row is still allowed to wrap — it lives inside a message
   body, is far narrower, and has no required order. */
.gcc-chat-ai-inline-row { flex-wrap: wrap; }


/* ══════════════════════════════════════════════════════════════════════════
 * 17. THE CUSTOM-DRAWN SELECT (js/gcc-select.js)
 * ══════════════════════════════════════════════════════════════════════════
 * A <select>'s dropdown is drawn by the operating system — its corners cannot be
 * rounded and the hover ground cannot be changed. The real element is hidden (and
 * kept as the value store) and the list redrawn in HTML, to match the rest of the page. */
.gcc-sel {
    position: relative;
    flex: 1 1 100%;
    min-width: 0;
}

/* The real element stays in the DOM for the engine to read, hidden only from view.
   NOT display:none: some browsers skip an element hidden that way when submitting a
   form and when measuring. */
.gcc-sel > select {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.gcc-sel-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    min-height: 34px;
    box-sizing: border-box;
    padding: 7px 12px;
    border: 1px solid var(--line, rgba(127, 127, 127, .35));
    border-radius: 10px;
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.gcc-sel-btn:hover { border-color: rgba(127, 127, 127, .55); }
.gcc-sel.is-open .gcc-sel-btn { border-color: rgba(127, 127, 127, .6); }
.gcc-sel.is-placeholder .gcc-sel-label { opacity: .6; }
.gcc-sel-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.gcc-sel-menu {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    /* It opens UPWARDS: the select sits near the foot of the screen (the compose box
       is pinned there), and opening downwards puts the list outside the viewport. */
    bottom: calc(100% + 6px);
    z-index: 50;
    /* The height is a MULTIPLE of one row (34px) plus the padding — so the bottom edge
       does not slice an item, which looks broken. The scrollbar is hidden, so nothing
       signals there is more below; scroll-snap stops each scroll at the top of a row,
       and the fade at the foot is what says "there is more". */
    max-height: calc(34px * 7 + 12px);
    overflow-y: auto;
    scroll-snap-type: y proximity;
    padding: 6px;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
    border: 1px solid var(--gcc-pnl-line);
    border-radius: 14px;
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
    scrollbar-width: none;
}

.gcc-sel-menu::-webkit-scrollbar { width: 0; height: 0; }
.gcc-sel.is-open .gcc-sel-menu { display: block; }

/* ── AND DOWNWARDS WHEN UPWARDS IS OFF THE SCREEN ──────────────────────────
   The rule above is right for the place it was written for and wrong everywhere
   else: the compose box is pinned to the foot of the window, so up is the only
   direction with room. The same select now appears at the HEAD of a step in the
   builder column, a few rows below the top of the page.

   Measured on the deployed site at 1440x739, the theme menu in the Photos step:
   top -127, bottom 123. A quarter of the list was above the window with no way
   to reach it — the scroll that would have reached it belongs to the menu, and
   the part that is missing is outside the menu's own box.

   The component measures the room on each side when it opens and writes this
   class when there is more below, which leaves the composer exactly as it was
   and is also the honest answer: neither direction is correct in general. */
.gcc-sel.is-down .gcc-sel-menu {
    top: calc(100% + 6px);
    bottom: auto;
}

.gcc-sel-item {
    display: flex;
    align-items: center;
    /* A FIXED 34px height: it matches the list's max-height arithmetic above, and
       equals the standard button height in the compose box exactly. */
    min-height: 34px;
    scroll-snap-align: start;
    width: 100%;
    box-sizing: border-box;
    padding: 0 10px;
    border: 0;
    border-radius: 9px;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.gcc-sel-item:hover { background: rgba(127, 127, 127, .18); }
.gcc-sel-item.is-active { background: rgba(127, 127, 127, .26); font-weight: 600; }


/* ══════════════════════════════════════════════════════════════════════════
 * 18. BUTTON HIERARCHY + ROW MERGING (js/gcc-compose-layout.js)
 * ══════════════════════════════════════════════════════════════════════════ */

/* The secondary button (the engine adds `secondary`: Skip, No thanks…) never had a
   style of its own and so used the PRIMARY one — two solid buttons side by side,
   looking like two ways of doing one thing. A secondary button has to be an OUTLINE:
   the same size, a different visual weight. */
.gcc-chat-btn.secondary,
:root[data-theme="dark"] .gcc-chat-btn.secondary,
:root:not([data-theme="light"]) .gcc-chat-btn.secondary {
    background: none;
    color: inherit;
    border: 1px solid var(--line, rgba(127, 127, 127, .4));
    font-weight: 500;
}

.gcc-chat-btn.secondary:hover { background: rgba(127, 127, 127, .14); }

/* A row already merged upwards: removed, so it does not leave a gap the height of
   a row. :empty cannot be used — the row still holds whitespace text nodes. */
.gcc-chat-actions-row.gcc-row-merged { display: none; }

/* A row that has just taken a button: the button goes right and the input keeps the rest. */
.gcc-row-has-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.gcc-row-has-btn > input,
.gcc-row-has-btn > textarea { flex: 1 1 180px; }

/* The select keeps a row of its own, and the buttons drop below and stand side by
   side. */
.gcc-row-has-btn > .gcc-sel { flex: 1 1 100%; }


/* A secondary button moved into the input row: its text and size stay as they were
   in a row of its own; only its place changes. */
.gcc-chat-input-row .gcc-row-secondary-btn {
    flex: 0 0 auto;
    width: auto;
    font-size: 13px;
}


/* ══════════════════════════════════════════════════════════════════════════
 * 19. LOCKED MEDIA (js/gcc-media-lock.js)
 * ══════════════════════════════════════════════════════════════════════════
 * Adapted from the WordPress module's assets/media-lock.css. The credit-related
 * part is dropped; the image blur and the padlock badge stay, because they read
 * immediately and need no explaining text. */

.gcc-mp-card[data-locked="1"] img,
.gcc-mp-card[data-locked="1"] .gcc-mp-thumb {
    filter: brightness(.55) saturate(.55);
    transition: filter .18s ease;
}

.gcc-mp-card[data-locked="1"]:hover img,
.gcc-mp-card[data-locked="1"]:hover .gcc-mp-thumb { filter: brightness(.68) saturate(.7); }

/* The padlock badge. pointer-events:none so the click falls through to the card
   below — the card is where the module listens. */
.gcc-item-lock {
    position: absolute;
    top: 6px;
    right: 6px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .68);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    pointer-events: none;
    backdrop-filter: blur(2px);
}

.gcc-item-lock .gcc-lock-icon { font-size: 11px; }

/* ── The upgrade dialog ── */
.gcc-ml-backdrop {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, .55);
}

.gcc-ml-dialog {
    width: min(380px, 100%);
    box-sizing: border-box;
    padding: 24px;
    border: 1px solid var(--gcc-pnl-line);
    border-radius: 18px;
    /* It uses this file's own tokens and does NOT borrow --card/--ink: both are
       redefined at a nearer level with light-theme values (measured: --card resolved to
       WHITE right inside the chat frame). */
    background: var(--gcc-pnl-bg);
    color: var(--gcc-pnl-fg);
    text-align: center;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}

.gcc-ml-icon  { font-size: 30px; line-height: 1; margin-bottom: 10px; }
.gcc-ml-title { margin: 0 0 8px; font-size: 16px; font-weight: 700; }
.gcc-ml-msg   { margin: 0 0 18px; font-size: 13px; line-height: 1.6; opacity: .75; }

/* The list of "what on this card belongs to a paid plan".
   LEFT-aligned inside a centred dialog: this is meant to be read and checked line by
   line, not a slogan. */
.gcc-tn-dialog { width: min(440px, 100%); }
.gcc-tn-list {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    text-align: left;
}
.gcc-tn-list li {
    padding: 10px 12px;
    margin-bottom: 8px;
    border-radius: 10px;
    border: 1px solid var(--gcc-pnl-line);
    background: rgba(127, 127, 127, .10);
}
.gcc-tn-list b { display: block; font-size: 13px; margin-bottom: 2px; }
.gcc-tn-list span { display: block; font-size: 12px; line-height: 1.5; opacity: .75; }

.gcc-ml-actions {
    display: flex;
    gap: 8px;
    justify-content: center;
    flex-wrap: wrap;
}

.gcc-ml-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    padding: 8px 18px;
    border-radius: 999px;
    border: 1px solid transparent;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.gcc-ml-cancel {
    background: none;
    color: inherit;
    border-color: var(--gcc-pnl-line);
}

.gcc-ml-cancel:hover { background: rgba(127, 127, 127, .16); }

.gcc-ml-go {
    background: #1d1d1f;
    color: #fff;
}

:root[data-theme="dark"] .gcc-ml-go,
:root:not([data-theme="light"]) .gcc-ml-go {
    background: #e8e8e8;
    color: #101010;
}

.gcc-ml-go:hover { opacity: .88; }


/* The administrator's plan chip: quite a different colour, so it is never mistaken
   for a real paid plan. Skipping the quotas while looking like an ordinary account is
   the root of every "it works on my machine". */
.gcc-ios-chip.gcc-ios-plan-dev {
    background: #6d4aff;
    color: #ffffff;
}


/* ══════════════════════════════════════════════════════════════════════════
 * ✨ PRESETS — moved up to the preview toolbar
 * ══════════════════════════════════════════════════════════════════════════
 * The old button floated directly above the card and its panel opened in place,
 * covering the top of the card — the very bug already fixed for the decoration and
 * size tools. The button now sits on .gcc-pv-bar and the panel drops from the top of the workspace column (js/gcc-presets-panel.js).
 *
 * THE BUTTON is hidden, not the whole wrapper: gcc-typography.js calls .show(), so
 * the wrapper carries an inline display:block — which no CSS rule reaches without
 * !important. The button has no inline style, and it is the only visible thing in
 * that wrapper, so hiding it is enough. The wrapper stays in the DOM for the mobile
 * build to read the preset list.
 */
.gcc-col--preview .gcc-typo-preset-trigger { display: none; }

.gcc-col--preview .gcc-typo-preset-wrap {
    margin: 0;
    padding: 0;
    min-height: 0;
}

.gcc-presets-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 8px;
    overflow-y: auto;
    min-height: 0;
    scrollbar-width: none;
}

.gcc-presets-grid::-webkit-scrollbar { width: 0; height: 0; }

/* It reuses the size picker's shape exactly, so the three panels read as one system. */
.gcc-presets-grid .gcc-typo-pm-btn {
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: 10px;
    background: rgba(127, 127, 127, .12);
    color: inherit;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    text-align: center;
    cursor: pointer;
}

.gcc-presets-grid .gcc-typo-pm-btn:hover { background: rgba(127, 127, 127, .22); }

.gcc-presets-grid .gcc-typo-pm-btn.active {
    background: rgba(127, 127, 127, .28);
    border-color: currentColor;
}

/* Reset is a different kind of action from choosing a preset — separated by a
   dashed rule rather than left looking like a fifth preset. */
.gcc-presets-grid .gcc-pm-reset {
    border-style: dashed;
    border-color: var(--gcc-pnl-line, rgba(127, 127, 127, .3));
    background: none;
    font-weight: 500;
}

.gcc-presets-empty { font-size: 12px; opacity: .6; }
