/* Holotype UI — views.css
   Major view surfaces + feedback: auth, pool deck, inbox,
   mating stage, error banner, toasts, discovery toast.
   Part 4/7 of the former styles.css; files are linked
   from index.html in order, so the cascade is unchanged. */

        /* ---- Auth UI — Expedition log-in --------------------------
           A small framed plate with a serif "Expedition log-in" title
           and a small-caps eyebrow. Same hairline double-rule chrome
           as the result card so the whole site feels like one
           bookbinding. */
        .auth-card {
            max-width: 440px;
            margin: 56px auto;
            padding: 36px 32px 32px;
            background: var(--bg-vellum);
            border: 1px solid var(--rule-strong);
            box-shadow:
                inset 0 0 0 4px var(--bg-vellum),
                inset 0 0 0 5px var(--rule),
                0 12px 32px rgba(0, 0, 0, 0.4);
            border-radius: 2px;
            position: relative;
        }
        .auth-card::before {
            content: "Expedition Log-in";
            display: block;
            font-family: var(--font-serif);
            font-size: 10.5px;
            font-weight: 600;
            letter-spacing: 0.22em;
            text-transform: uppercase;
            color: var(--copper);
            font-feature-settings: "smcp", "lnum";
            margin-bottom: 10px;
        }
        .auth-card h2 {
            margin: 0 0 8px;
            font-family: var(--font-serif);
            font-size: 24px;
            font-weight: 500;
            color: var(--ink);
        }
        .auth-card p {
            margin: 0 0 22px;
            font-family: var(--font-serif);
            font-style: italic;
            color: var(--ink-muted);
            font-size: 14px;
            line-height: 1.5;
        }
        .auth-card form {
            display: flex;
            flex-direction: column;
            gap: 14px;
        }
        .auth-card input {
            padding: 12px 14px;
            font-family: var(--font-sans);
            font-size: 15px;
            border: 1px solid var(--rule-strong);
            border-radius: 2px;
            background: var(--bg-ink);
            box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5);
            color: var(--ink);
            transition: border-color var(--motion-quick),
                        box-shadow var(--motion-quick);
        }
        .auth-card input:focus {
            outline: none;
            border-color: var(--copper);
            box-shadow: 0 0 0 2px var(--copper-dim);
        }
        .auth-card input[name="code"] {
            font-family: var(--font-mono);
            font-size: 24px;
            font-weight: 500;
            letter-spacing: 0.4em;
            text-align: center;
            color: var(--copper);
        }
        .auth-card button[type="submit"] {
            padding: 12px 14px;
            font-family: var(--font-serif);
            font-size: 12.5px;
            font-weight: 600;
            letter-spacing: 0.18em;
            text-transform: uppercase;
            font-feature-settings: "smcp", "lnum";
            background: var(--copper);
            color: var(--bg-ink);
            border: 1px solid var(--copper);
            border-radius: 1px;
            cursor: pointer;
            transition: background var(--motion-quick),
                        border-color var(--motion-quick);
        }
        .auth-card button[type="submit"]:hover:not(:disabled) {
            background: var(--copper-hover);
            border-color: var(--copper-hover);
        }
        .auth-card button[type="submit"]:disabled {
            opacity: 0.55;
            cursor: not-allowed;
        }
        .auth-card .auth-back {
            margin: 16px 0 0;
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 13px;
        }
        .auth-card .auth-back a {
            color: var(--ink-muted);
        }
        .auth-error {
            margin: 12px 0 0;
            padding: 10px 14px;
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 13px;
            color: var(--ink);
            background: var(--oxblood-bg);
            border: 1px solid var(--oxblood);
            border-radius: 1px;
        }
        .auth-error[hidden] { display: none; }

        /* Header row layout — title on left, account drawer on right
           when authenticated. */
        header .header-row {
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: 16px;
        }
        /* Mode menu — the app's major views (Library / Pool / Inbox /
           Compendium), a small brass menu set into the leather
           titlebar. App-level chrome, distinct from the book's side
           bookmarks. Hidden until auth resolves. */
        #top-nav {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        #top-nav[hidden] { display: none; }
        /* Top-nav buttons: framed brass tabs in the same engraved
           vocabulary as the .book-bookmark side tabs, but horizontal.
           They previously sat as transparent text against the leather
           page, which made them nearly invisible on the brown
           background. Giving them the same dark gradient + rule-strong
           border + box-shadow treatment as the side ribbons pulls them
           up off the leather so the labels are readable, while
           preserving the brass-on-leather chrome that defines the app. */
        #top-nav button {
            /* inline-flex + centered content + a fixed min-height so a button
               with a badge (Inbox) is exactly the same height as the plain
               ones — the badge is centered within and can't stretch the tab. */
            display: inline-flex;
            align-items: center;
            box-sizing: border-box;
            min-height: 26px;
            padding: 5px 13px;
            font-family: var(--font-serif);
            font-size: 11px;
            font-weight: 600;
            letter-spacing: 0.15em;
            text-transform: uppercase;
            font-feature-settings: "smcp", "lnum";
            background: linear-gradient(to bottom,
                rgba(10, 7, 5, 0.92), rgba(22, 15, 11, 0.74));
            border: 1px solid var(--rule-strong);
            border-radius: 3px;
            color: var(--ink-muted);
            cursor: pointer;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
            transition:
                color var(--motion-quick),
                background var(--motion-quick),
                border-color var(--motion-quick);
        }
        #top-nav button:hover {
            color: var(--ink);
            border-color: var(--copper);
        }
        /* The active mode is a struck-brass index tab — the same
           brass-face + bevel as the active book bookmark and the masthead
           nameplate, so every "selected" element across the frame is the
           same metal. Dark ink on brass keeps the label crisp. */
        #top-nav button.is-active {
            color: var(--bg-ink);
            background: var(--brass-face);
            border-color: var(--copper);
            text-shadow: var(--text-emboss);
            box-shadow: var(--bevel-raised);
        }
        /* Unread-count badge sits inside the nav button. Restyled as
           a small copper pill with serif numerals. */
        #top-nav .nav-badge {
            /* A compact count pill, sized well under the button's min-height
               so it stays a small accent rather than bulking the tab. */
            display: inline-flex;
            align-items: center;
            justify-content: center;
            margin-left: 6px;
            min-width: 14px;
            height: 14px;
            padding: 0 4px;
            box-sizing: border-box;
            font-family: var(--font-serif);
            font-size: 9px;
            font-weight: 600;
            letter-spacing: 0.02em;
            color: var(--bg-ink);
            background: var(--copper);
            border-radius: 7px;
            font-variant-numeric: tabular-nums lining-nums;
            line-height: 1;
            text-transform: none;
        }
        #top-nav .nav-badge[hidden] { display: none; }
        #account-drawer {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 13px;
            color: var(--ink-muted);
            flex-shrink: 0;
        }
        #account-drawer[hidden] { display: none; }

        /* Compendium goal chip — the game's one goal, kept in the
           titlebar so it is always in view. */
        /* (The titlebar goal-progress chip was retired — alleles-discovered now
           renders as the XP bar in the action dock; see .dock-xpbar in
           layout.css.) */
        .account-email {
            font-family: var(--font-mono);
            font-size: 12px;
            color: var(--ink-muted);
            letter-spacing: 0.04em;
        }

        /* ---- Pool (swipe deck) ----------------------------------
           A single big card centered, with Pass / Mate buttons below.
           Top card is fully visible; future cards are pre-rendered
           offset behind it as a hint. */
        #pool-section {
            max-width: 520px;
            margin: 0 auto;
            padding-top: 8px;
        }
        .pool-partner-picker {
            margin-bottom: 16px;
            padding: 12px 16px;
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: var(--radius);
        }
        .pool-partner-picker .pool-partner-label {
            display: block;
            font-size: 12px;
            text-transform: uppercase;
            letter-spacing: 0.06em;
            color: var(--text-muted);
            margin-bottom: 6px;
        }
        .pool-partner-picker .pool-partner-none {
            color: var(--text-muted);
            font-size: 13px;
            font-style: italic;
        }
        .pool-deck-area {
            position: relative;
            min-height: 480px;
        }
        /* Pool deck — the registry of pooled specimens, presented one
           at a time as a hairline-rule plate. Decision actions read as
           field-journal verbs (Pass / Cross). */
        .pool-card {
            background: var(--bg-vellum);
            border: 1px solid var(--rule-strong);
            box-shadow:
                inset 0 0 0 4px var(--bg-vellum),
                inset 0 0 0 5px var(--rule),
                0 8px 28px rgba(0, 0, 0, 0.4);
            border-radius: 2px;
            overflow: hidden;
        }
        .pool-card-image {
            width: 100%;
            aspect-ratio: 1;
            object-fit: cover;
            background: var(--bg-ink);
            display: block;
            border-bottom: 1px solid var(--rule);
        }
        .pool-card-image-placeholder {
            width: 100%;
            aspect-ratio: 1;
            background: var(--bg-ink);
            display: flex;
            align-items: center;
            justify-content: center;
            color: var(--ink-faint);
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 13px;
            border-bottom: 1px solid var(--rule);
        }
        .pool-card-meta {
            padding: 18px 22px 22px;
        }
        .pool-card-name {
            font-family: var(--font-serif);
            font-size: 22px;
            font-weight: 500;
            margin: 0 0 4px;
            color: var(--ink);
            letter-spacing: 0.005em;
        }
        .pool-card-owner {
            font-size: 11px;
            color: var(--ink-faint);
            font-family: var(--font-mono);
            letter-spacing: 0.04em;
        }
        .pool-card-traits {
            margin-top: 12px;
            font-family: var(--font-serif);
            font-size: 13.5px;
            font-style: italic;
            color: var(--ink-muted);
            line-height: 1.55;
        }
        .pool-card-counter {
            text-align: center;
            font-family: var(--font-serif);
            font-size: 10.5px;
            color: var(--copper);
            margin: 14px 0;
            text-transform: uppercase;
            letter-spacing: 0.22em;
            font-feature-settings: "smcp", "lnum";
        }
        .pool-actions {
            display: flex;
            gap: 12px;
            margin-top: 16px;
        }
        .pool-actions button {
            flex: 1;
            padding: 14px;
            font-family: var(--font-serif);
            font-size: 13px;
            font-weight: 600;
            letter-spacing: 0.18em;
            text-transform: uppercase;
            font-feature-settings: "smcp", "lnum";
            border-radius: 1px;
            cursor: pointer;
            transition: filter var(--motion-quick), transform var(--motion-quick);
        }
        .pool-actions button:hover { filter: brightness(1.05); }
        .pool-actions button:active { transform: translateY(1px); }
        .pool-actions .pool-pass {
            background: transparent;
            color: var(--ink-muted);
            border: 1px solid var(--rule-strong);
        }
        .pool-actions .pool-pass:hover {
            color: var(--ink);
            border-color: var(--ink-muted);
        }
        .pool-actions .pool-mate {
            background: var(--copper);
            color: var(--bg-ink);
            border: 1px solid var(--copper);
        }
        .pool-actions .pool-mate:hover {
            background: var(--copper-hover);
            border-color: var(--copper-hover);
        }
        .pool-empty {
            text-align: center;
            padding: 64px 20px;
            color: var(--ink-muted);
        }
        .pool-empty h3 {
            margin: 0 0 8px;
            font-family: var(--font-serif);
            font-size: 22px;
            font-weight: 500;
            color: var(--ink);
        }

        /* ---- Inbox -----------------------------------------------
           Two-tab list of mating proposals. Each row is clickable
           and opens the review modal. */
        #inbox-section {
            max-width: 720px;
            margin: 0 auto;
        }
        /* Inbox — incoming and outgoing correspondence. Each row is a
           folded letter with a status seal in the corner. */
        .inbox-tabs {
            display: flex;
            gap: 0;
            border-bottom: 1px solid var(--rule);
            margin-bottom: 22px;
        }
        .inbox-tabs button {
            padding: 10px 18px 12px;
            font-family: var(--font-serif);
            font-size: 12px;
            font-weight: 600;
            letter-spacing: 0.18em;
            text-transform: uppercase;
            font-feature-settings: "smcp", "lnum";
            background: none;
            border: none;
            border-bottom: 2px solid transparent;
            color: var(--ink-muted);
            cursor: pointer;
            margin-bottom: -1px;
            transition: color var(--motion-quick), border-color var(--motion-quick);
        }
        .inbox-tabs button:hover { color: var(--ink); }
        .inbox-tabs button.is-active {
            color: var(--copper);
            border-bottom-color: var(--copper);
        }
        .inbox-list {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        /* Each received/sent proposal is a specimen plate in the feed
           (shared .fj-plate kit, added in render) — only the row's grid
           layout + the slide-out hover stay here. */
        .inbox-row {
            display: grid;
            grid-template-columns: 56px 1fr 18px auto;
            gap: 14px;
            align-items: center;
            padding: 12px 18px;
            cursor: pointer;
            position: relative;
            transition: border-color var(--motion-quick), transform var(--motion-quick);
        }
        .inbox-row:hover {
            border-color: var(--copper);
            transform: translateX(2px);
        }
        .inbox-row img {
            width: 56px;
            height: 56px;
            border-radius: 1px;
            object-fit: cover;
            background: var(--bg-ink);
            border: 1px solid var(--rule);
        }
        .inbox-row-meta .partner {
            font-family: var(--font-serif);
            font-weight: 500;
            font-size: 16px;
            color: var(--ink);
            letter-spacing: 0.005em;
        }
        .inbox-row-meta .status-line {
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 12.5px;
            color: var(--ink-muted);
            margin-top: 2px;
        }
        /* Status seal — small wax-stamp dot rendered in the dedicated
           grid column to the right of the meta. Color encodes status. */
        .inbox-row .status-seal {
            display: block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            box-shadow: 0 0 0 2px var(--bg-vellum), 0 0 0 3px currentColor;
            background: currentColor;
            opacity: 0.85;
        }
        .inbox-row.status-pending .status-seal     { color: var(--copper); }
        .inbox-row.status-finalized .status-seal   { color: var(--sage); }
        .inbox-row.status-declined .status-seal,
        .inbox-row.status-cancelled .status-seal,
        .inbox-row.status-expired .status-seal     { color: var(--ink-faint); }
        .inbox-row .status-arrow {
            font-family: var(--font-serif);
            font-size: 18px;
            color: var(--ink-faint);
        }
        .inbox-status-pending   { color: var(--copper); font-style: normal !important; font-weight: 600; }
        .inbox-status-finalized { color: var(--sage); font-style: normal !important; font-weight: 600; }
        .inbox-status-declined,
        .inbox-status-cancelled,
        .inbox-status-expired { color: var(--ink-faint); }
        .inbox-empty {
            text-align: center;
            padding: 56px 24px;
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 14px;
            color: var(--ink-muted);
        }
        /* Inbox badge styling lives on #top-nav .nav-badge in the
           Phase-3 nav block; nothing extra here. */

        /* "Send mating request" modal — reuses the .modal pattern from
           the existing save / mate modals. */
        .request-modal-content { max-width: 460px; }
        .request-modal-content textarea {
            width: 100%;
            min-height: 60px;
            padding: 8px 10px;
            font-family: inherit;
            font-size: 13px;
            border: 1px solid var(--border);
            border-radius: 6px;
            background: var(--bg);
            color: var(--text);
            resize: vertical;
        }
        /* Review-proposal modal layout — split: proposer's creature on
           left, addressee's pick on right (when accepting). */
        .review-modal-content { max-width: 560px; }
        .review-summary {
            display: flex;
            gap: 12px;
            margin-bottom: 12px;
            padding: 10px;
            background: var(--surface-2);
            border-radius: 6px;
            align-items: center;
        }
        .review-summary img {
            width: 60px;
            height: 60px;
            border-radius: 6px;
            object-fit: cover;
        }

        #loading-section {
            text-align: center;
            padding: 60px 0;
        }
        /* Field loader — a surveyor's compass: a static engraved bezel
           with a copper needle that sweeps round while the server
           works. Replaces a generic CSS border-spinner so the wait
           still reads as the field-journal. */
        .field-loader {
            display: block;
            width: 54px;
            height: 54px;
            margin: 0 auto 18px;
        }
        .field-loader .fl-ring {
            fill: none;
            stroke: var(--rule-strong);
            stroke-width: 1.4;
        }
        .field-loader .fl-ring-inner { stroke: var(--rule); }
        .field-loader .fl-ticks {
            fill: none;
            stroke: var(--ink-faint);
            stroke-width: 1.6;
            stroke-linecap: round;
        }
        .field-loader .fl-needle {
            transform-origin: 24px 24px;
            animation: fl-sweep 1.9s ease-in-out infinite;
        }
        .field-loader .fl-n { fill: var(--copper); }
        .field-loader .fl-s { fill: var(--ink-faint); }
        .field-loader .fl-hub {
            fill: var(--bg-vellum);
            stroke: var(--brass);
            stroke-width: 1.2;
        }
        @keyframes fl-sweep { to { transform: rotate(360deg); } }
        /* Loading status — a handwritten note, as if the collector
           jotted "still working" in the margin while they wait. */
        .loading-text {
            font-family: var(--font-hand);
            font-size: 19px;
            color: var(--ink-pen);
            line-height: 1.3;
        }
        .loading-actions {
            margin-top: 24px;
        }

        /* ---- Mating stage ----
           Two parent specimen plates floating on either side of an
           animated copper ampersand. Replaces the default spinner
           during a mating so the wait reads as "the cross is
           happening" rather than "the page is loading". */
        .mating-stage {
            display: grid;
            grid-template-columns: 1fr auto 1fr;
            align-items: center;
            justify-items: center;
            gap: 24px;
            padding: 32px 16px 60px;
            min-height: 540px;
            position: relative;
        }
        .mating-stage[hidden] { display: none; }

        /* Each parent renders inside this fixed-aspect plate. The
           inner markup is built by JS via renderMatingStage(). */
        .mating-stage-card {
            position: relative;
            width: 100%;
            max-width: 320px;
            aspect-ratio: 5 / 7;
            background:
                linear-gradient(var(--bg-vellum), var(--bg-vellum)) padding-box,
                linear-gradient(var(--copper), var(--copper)) border-box;
            border: 6px solid transparent;
            box-shadow:
                inset 0 0 0 1px var(--brass),
                inset 0 0 0 3px var(--bg-vellum),
                inset 0 0 0 4px var(--rule),
                0 14px 36px rgba(0, 0, 0, 0.55),
                0 0 32px rgba(201, 139, 86, 0.18);
            border-radius: 4px;
            overflow: hidden;
            /* Slow up-down drift, distinct phase per side so the
               two cards "breathe" against each other. Slight rotation
               adds physical weight without feeling like a card-flip. */
            animation: mating-drift 5.5s ease-in-out infinite;
            will-change: transform;
        }
        .mating-stage-card--left {
            justify-self: end;
            transform-origin: 70% 50%;
            animation-delay: -2.75s;          /* opposite phase from right */
        }
        .mating-stage-card--right {
            justify-self: start;
            transform-origin: 30% 50%;
        }
        @keyframes mating-drift {
            0%, 100% { transform: translateY(-6px) rotate(-1.2deg); }
            50%      { transform: translateY( 6px) rotate( 1.2deg); }
        }

        /* Inner card pieces — match the result-card vocabulary at
           reduced scale: plate eyebrow, serif title, art window,
           type-line. No stats / flavor (those land later). */
        .mating-stage-card .mc-plate,
        .mate-stage-card .mc-plate {
            display: block;
            padding: 10px 14px 4px;
            font-family: var(--font-serif);
            font-size: 9.5px;
            font-weight: 600;
            letter-spacing: 0.22em;
            text-transform: uppercase;
            color: var(--copper);
            font-feature-settings: "smcp", "lnum";
        }
        .mating-stage-card .mc-title,
        .mate-stage-card .mc-title {
            margin: 0;
            padding: 0 14px 8px;
            font-family: var(--font-serif);
            font-size: 18px;
            font-weight: 500;
            letter-spacing: 0.005em;
            color: var(--ink);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .mating-stage-card .mc-art,
        .mate-stage-card .mc-art {
            position: relative;
            margin: 0 14px;
            aspect-ratio: 1 / 1;
            background: var(--bg-ink);
            border: 1px solid var(--rule-strong);
            box-shadow:
                inset 0 0 0 1px var(--bg-vellum),
                inset 0 0 0 2px var(--copper);
        }
        .mating-stage-card .mc-art img,
        .mate-stage-card .mc-art img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
        }
        .mating-stage-card .mc-typeline,
        .mate-stage-card .mc-typeline {
            margin: 10px 14px 0;
            padding: 6px 0;
            font-family: var(--font-serif);
            font-size: 10.5px;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            color: var(--ink-muted);
            border-top: 1px solid var(--rule);
            border-bottom: 1px solid var(--rule);
            text-align: center;
            font-feature-settings: "smcp", "lnum";
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        /* Bridge — copper "&" glyph that pulses, plus a serif status
           line below it. The glyph carries the meaning ("these two
           crossing"); status text gives the timing cue. */
        .mating-stage-bridge {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 14px;
            min-width: 180px;
            padding: 0 12px;
        }
        .mating-stage-amp {
            font-family: var(--font-serif);
            font-style: italic;
            font-size: 96px;
            font-weight: 500;
            line-height: 1;
            color: var(--copper);
            text-shadow: 0 0 24px rgba(201, 139, 86, 0.55);
            animation: mating-amp-pulse 2.4s ease-in-out infinite;
        }
        @keyframes mating-amp-pulse {
            0%, 100% {
                opacity: 0.7;
                transform: scale(0.98);
                text-shadow: 0 0 20px rgba(201, 139, 86, 0.35);
            }
            50% {
                opacity: 1;
                transform: scale(1.04);
                text-shadow: 0 0 36px rgba(201, 139, 86, 0.75);
            }
        }
        .mating-stage-status {
            font-family: var(--font-serif);
            font-size: 13px;
            font-weight: 600;
            letter-spacing: 0.18em;
            text-transform: uppercase;
            color: var(--copper);
            font-feature-settings: "smcp", "lnum";
            text-align: center;
        }
        .mating-stage-status-sub {
            font-family: var(--font-hand);
            font-size: 16px;
            color: var(--ink-pen);
            text-align: center;
            max-width: 220px;
            line-height: 1.3;
        }

        /* Mobile — stack the cards above/below the bridge. */
        @media (max-width: 720px) {
            .mating-stage {
                grid-template-columns: minmax(0, 1fr);
                grid-template-rows: auto auto auto;
                gap: 18px;
                padding: 24px 12px 48px;
                min-height: 0;
            }
            .mating-stage-card {
                max-width: 240px;
            }
            .mating-stage-card--left,
            .mating-stage-card--right {
                justify-self: center;
            }
            .mating-stage-amp { font-size: 72px; }
        }

        /* ---- Error banner ---- */

        .error-banner {
            display: none;
            background: var(--danger-bg);
            border: 1px solid var(--danger-border);
            color: var(--danger);
            padding: 12px 16px;
            border-radius: var(--radius);
            margin: 20px 0 0;
            font-size: 14px;
        }
        .error-banner.is-visible { display: block; }
        .error-banner strong { font-weight: 600; }

        /* ---- Toast ----
           A transient in-theme notice — a framed parchment slip that
           slides down from under the titlebar and fades out. Replaces
           native alert() so advisories keep the field-journal voice. */
        /* Three fixed top-centre banners share this column — the persistent
           brew-pill (78px), this advisory toast (132px), and the discovery
           toast (186px) each get their OWN band so any combination stacks
           instead of rendering on top of one another. (They used to all pin to
           top:78px; a brew-pill + a concurrent toast fully hid the lower one.) */
        .toast {
            position: fixed;
            top: 132px;
            left: 50%;
            transform: translateX(-50%) translateY(-10px);
            z-index: 90;
            max-width: 440px;
            padding: 11px 18px;
            background: var(--bg-vellum);
            border: 1px solid var(--rule-strong);
            border-left: 3px solid var(--oxblood);
            box-shadow:
                inset 0 0 0 3px var(--bg-vellum),
                inset 0 0 0 4px var(--rule),
                0 10px 28px rgba(0, 0, 0, 0.55);
            font-family: var(--font-serif);
            font-size: 14px;
            line-height: 1.5;
            color: var(--ink);
            opacity: 0;
            pointer-events: none;
            transition:
                opacity var(--motion-base),
                transform var(--motion-base);
        }
        .toast[hidden] { display: none; }
        .toast.is-visible {
            opacity: 1;
            transform: translateX(-50%) translateY(0);
        }
        .toast.is-tappable {
            pointer-events: auto;
            cursor: pointer;
            border-left-color: var(--copper);
        }

        /* ---- Discovery toast ----
           Fires alongside the inline discovery strip when a creation
           emits novel DiscoveryEvents. The strip says "your compendium
           gained N cells"; the toast says "here are the specific novel
           alleles that came out of this cross". Gold-leaf accent for
           any first_discovery in the batch (matching the discovery
           strip's reward palette); plain copper for novel-variant-only
           batches. Hover pauses the dismiss timer; click dismisses. */
        .discovery-toast {
            position: fixed;
            top: 186px;                 /* own band — see the .toast note above */
            left: 50%;
            transform: translateX(-50%) translateY(-10px);
            z-index: 91;
            max-width: 480px;
            min-width: 280px;
            padding: 12px 18px;
            background: var(--bg-vellum);
            border: 1px solid var(--rule-strong);
            border-left: 3px solid var(--copper);
            box-shadow:
                inset 0 0 0 3px var(--bg-vellum),
                inset 0 0 0 4px var(--rule),
                0 10px 28px rgba(0, 0, 0, 0.55);
            font-family: var(--font-serif);
            font-size: 14px;
            line-height: 1.45;
            color: var(--ink);
            opacity: 0;
            pointer-events: none;
            cursor: pointer;
            transition:
                opacity var(--motion-base),
                transform var(--motion-base);
        }
        .discovery-toast[hidden] { display: none; }
        .discovery-toast.is-visible {
            opacity: 1;
            transform: translateX(-50%) translateY(0);
            pointer-events: auto;
        }
        .discovery-toast.is-first-discovery {
            border-left-color: var(--gold-leaf);
            box-shadow:
                inset 0 0 0 3px var(--bg-vellum),
                inset 0 0 0 4px var(--rule),
                0 10px 28px rgba(0, 0, 0, 0.55),
                0 0 24px var(--gold-leaf-glow);
        }
        .discovery-toast-title {
            font-family: var(--font-hand);
            font-size: 17px;
            font-weight: 600;
            color: var(--copper);
            margin: 0 0 8px;
        }
        .discovery-toast.is-first-discovery .discovery-toast-title {
            color: var(--gold-leaf);
        }
        .discovery-toast-events {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        .discovery-toast-event {
            padding: 6px 0 0;
            border-top: 1px solid var(--rule);
        }
        .discovery-toast-event:first-child {
            padding-top: 0;
            border-top: none;
        }
        .discovery-toast-locus {
            font-weight: 600;
            font-size: 13px;
            letter-spacing: 0.04em;
            text-transform: uppercase;
            color: var(--ink);
        }
        .discovery-toast-summary {
            color: var(--ink);
            font-size: 13px;
            margin: 1px 0 0;
        }
        .discovery-toast-count {
            color: var(--text-muted);
            font-size: 12px;
            font-style: italic;
            margin: 1px 0 0;
        }

        /* Brew pill — a persistent notice shown while a creature is
           being drawn in the background, so the player knows it is
           safe to keep browsing instead of watching a spinner. */
        .brew-pill {
            position: fixed;
            top: 78px;                  /* topmost band — see the .toast note (78/132/186) */
            left: 50%;
            transform: translateX(-50%);
            z-index: 89;
            display: inline-flex;
            align-items: center;
            gap: 10px;
            padding: 9px 18px;
            background: var(--bg-vellum);
            border: 1px solid var(--rule-strong);
            border-left: 3px solid var(--copper);
            box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
            font-family: var(--font-serif);
            font-size: 13.5px;
            font-style: italic;
            color: var(--ink-muted);
        }
        .brew-pill[hidden] { display: none; }
        .brew-pill::before {
            content: "";
            width: 12px;
            height: 12px;
            border: 2px solid var(--rule-strong);
            border-top-color: var(--copper);
            border-radius: 50%;
            animation: brew-spin 0.9s linear infinite;
        }
        @keyframes brew-spin { to { transform: rotate(360deg); } }
        @media (prefers-reduced-motion: reduce) {
            .brew-pill::before { animation: none; }
        }

