/* ============================================================
   prntr - warm paper / coral theme
   Follows the reworked "New order" design: solid white cards with a
   hairline warm-grey border, generous radii, warm neutral type, ink
   (near-black) as the primary action colour and coral used sparingly
   as the accent. The page backdrop (print mosaic + coral wash) is
   unchanged and still dark, so anything sitting directly on the
   canvas keeps the light --on-bg colours.
   Class names match the pages so they re-skin in place; page-level
   inline styles reference the tokens below, which is why the token
   names are kept stable even when their values change.
   ============================================================ */

:root {
    /* Coral scale - warm, less saturated than the old graphite theme */
    --coral-100:#f7ece7; --coral-300:#f0a98f; --coral-400:#ef8a68;
    --coral:#e2603c; --coral-600:#c9553a; --coral-700:#b4553a; --coral-900:#a8422b;
    --accent:#e2603c;
    --accent-a40:rgba(226,96,60,.35);

    /* Sage - the single "all good" signal (online, location attached, success).
       Kept under the legacy --blue-* names so existing inline styles follow along. */
    --ok:#5f9c80; --ok-fg:#7c968a; --ok-bg:#f1f6f3;
    --blue-100:var(--ok-bg); --blue-300:#cddcd4; --blue-700:var(--ok); --blue-900:#3f6f5b;

    /* Filament accents (single-hue aliases, kept for status weights) */
    --fil-orange:#e2603c; --fil-magenta:#c9553a; --fil-purple:#b4553a; --fil-cyan:#ef8a68;
    --fil-lime:#5f9c80; --fil-yellow:#d9963c; --fil-red:#c0492f; --fil-blue:#5f8a9c;

    /* Canvas (dark, behind the mosaic) + warm paper surfaces on top of it */
    --bg:#20242b;
    --bg2:#fdfcfb;                            /* input / inset on a panel */
    --bg-2:var(--bg2);                        /* hyphen alias (legacy inline styles) */
    --panel:#ffffff;                          /* card surface */
    --panel2:#f7f5f2;                         /* quiet inset (AI bubble, wells) */
    --panel-2:var(--panel2);
    --panel3:#f2efeb;                         /* pressed / selected neutral */
    --ink:#22201e;                            /* text on panels */
    --ink-2:#332f2b;                          /* body copy inside bubbles */
    --ink-btn:#22201e;                        /* primary action */
    --ink-btn-hover:#3a352f;
    --dim:#6e6862;                            /* secondary text on panels */
    --dim-2:#8b857e;
    --dim-3:#948d86;                          /* labels, meta */
    --ink-dim:var(--dim);
    --line:#e9e5e0;                           /* hairline border */
    --line-strong:#d6d0c9;                    /* hover border */
    --hair:#f1eeea;                           /* internal divider */
    --on-bg:#e9e7e2;                          /* text directly on the dark canvas */
    --on-bg-dim:#c3bdb5;
    --glass:saturate(1.05) blur(10px);
    --viewer:linear-gradient(180deg,#fcfbfa,#f4f1ee);
    --shade:rgba(255,255,255,.86);
    --hatch:rgba(35,39,46,.045);

    /* Elevation - flat on paper, but the cards float over a dark backdrop
       so they keep a soft warm drop shadow. */
    --shadow-card:0 10px 30px -20px rgba(90,45,25,.45), 0 1px 2px rgba(30,26,22,.05);
    --shadow-float:0 8px 24px -12px rgba(120,55,35,.28), 0 1px 2px rgba(120,55,35,.06);

    /* Status tags */
    --t-open-bg:#f1f6f3;               --t-open-fg:#4f8a70;
    --t-awarded-bg:rgba(226,96,60,.13); --t-awarded-fg:#b4553a;
    --t-printing-bg:#e2603c;           --t-printing-fg:#fff;
    --t-ready-bg:rgba(226,96,60,.26);  --t-ready-fg:#a8422b;
    --t-done-bg:#f2efeb;               --t-done-fg:#6e6862;

    --radius:20px;
    --radius-sm:13px;
    --radius-chip:11px;
}

* { box-sizing: border-box; }

html, body {
    height: 100%;
    overflow: hidden;
    margin: 0; padding: 0;
    color: var(--on-bg);
    font-family: 'Nunito', system-ui, -apple-system, sans-serif;
    font-size: 16px; line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}
/* Dark canvas on <html> only; <body> stays transparent so the fixed z-index:-1
   backdrop (in App.razor body) is not occluded by an opaque body background. */
html { background: var(--bg); }
body { background: transparent; }

a { color: var(--coral-600); text-decoration: none; }
a:hover { color: var(--coral-900); text-decoration: underline; }

h1, h2, h3 { margin: 0 0 .5rem; font-weight: 800; letter-spacing: -.025em; line-height: 1.2; }
h1 { font-size: 1.8rem; }
h2 { font-size: 1.3rem; }
h3 { font-size: 1.05rem; }

button, input, select, textarea { font-family: 'Nunito', system-ui, sans-serif; }

.muted { color: var(--on-bg-dim); }
.panel .muted, .card .muted, .auth-wrap .muted, .modal .muted { color: var(--dim-2); }
.small { font-size: .85rem; }

/* ---------- Scrollbars ---------- */
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #e4e0db; border-radius: 99px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: #d6d0c9; background-clip: content-box; }
* { scrollbar-width: thin; scrollbar-color: #e4e0db transparent; }

/* ---------- App shell (fixed height, backdrop, header, content) ---------- */
.app-shell {
    position: relative;
    height: 100vh;
    display: flex; flex-direction: column;
    background: transparent; color: var(--on-bg);
    overflow: hidden;
}
/* Backdrop lives in App.razor body (outside Blazor's interactive tree) so navigation never
   wipes it; sits behind everything at z-index:-1 over the body's dark canvas. */
.app-bg, .app-wash {
    position: fixed; inset: 0; z-index: -1; pointer-events: none;
}
/* White-gutter mosaic (darken on the tile images), with a single coral gradient
   wash on top covering EVERYTHING - tiles and the white gutters alike. No parallax. */
.app-bg { overflow: hidden; background: var(--bg); }
.app-bg .wall-grid { position: absolute; top: 0; left: 0; display: grid; }
.app-bg .wall-tile { position: relative; overflow: hidden; background: var(--bg); }
/* Two stacked layers per tile so swaps crossfade - the next image sits under the
   current one and fades in on top; the old one only hides once the new is shown. */
.app-bg .wall-tile img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: brightness(.34) contrast(1.05) saturate(.85);
    transition: opacity .9s ease-in-out;
}
.app-wash {
    background:
        linear-gradient(160deg, rgba(244,96,60,.3), rgba(176,54,31,.16) 55%, rgba(32,36,43,.5)),
        radial-gradient(120% 80% at 50% 0%, rgba(255,138,102,.16), transparent 60%);
}

/* Header is a detached white card floating over the backdrop. */
.topbar {
    position: relative; z-index: 50; flex: none; isolation: isolate;
    display: flex; align-items: center; gap: .9rem;
    margin: .9rem 1.5rem 0;
    padding: .6rem .7rem .6rem 1.1rem;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line); border-radius: 18px;
    box-shadow: var(--shadow-float);
}

/* Wordmark: plain ink with a coral full stop. */
.brand {
    display: inline-flex; align-items: baseline; flex: none;
    font-weight: 800; font-size: 1.32rem; letter-spacing: -.03em; line-height: 1;
    color: var(--ink);
}
.brand:hover { text-decoration: none; color: var(--ink); }
.brand .dot { color: var(--accent); }

.topbar .vline { width: 1px; height: 22px; background: var(--line); flex: none; margin: 0 .3rem; }

/* Persona switcher (customer <-> print shop), left of the nav. Segmented control:
   the whole track is inset, the selected half is raised on white. */
.modeswitch {
    display: flex; flex: none; gap: 2px; margin: 0;
    padding: 3px; border-radius: 12px; background: var(--panel3);
}
.modeswitch button {
    display: inline-flex; align-items: center; gap: .35rem;
    border: none; border-radius: 9px; padding: .32rem .6rem;
    background: transparent; color: var(--dim); font: inherit; font-size: .8rem; font-weight: 700;
    white-space: nowrap; cursor: pointer;
}
.modeswitch button i { font-size: .95rem; opacity: .7; }
.modeswitch button:hover { color: var(--ink); }
.modeswitch button.active {
    background: var(--panel); color: var(--ink);
    box-shadow: 0 1px 2px rgba(30,26,22,.12);
}
.modeswitch button.active i { opacity: 1; color: var(--coral-600); }
@media (max-width: 900px) { .modeswitch button span, .modeswitch button { font-size: .74rem; } }

/* Nav pills - quiet by default, a neutral wash marks the current page */
.navpills { display: flex; align-items: center; gap: .2rem; flex: 1 1 0; min-width: 0; flex-wrap: nowrap; overflow-x: auto; }
.navpill {
    display: inline-flex; align-items: center; gap: .42rem;
    border: none; background: transparent; color: var(--dim);
    border-radius: var(--radius-chip); padding: .5rem .85rem; font: inherit; font-size: .9rem;
    white-space: nowrap; font-weight: 600; cursor: pointer; text-decoration: none;
}
.navpill i { font-size: 1.05rem; opacity: .6; }
.navpill:hover { text-decoration: none; background: #f5f1ed; color: var(--ink); }
.navpill.active { background: var(--panel3); color: var(--ink); font-weight: 700; }
.navpill.active i { opacity: .75; }

/* Square icon buttons in the header (support, bell, etc.) */
.iconbtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; flex: none;
    border: none; background: transparent; color: var(--dim);
    border-radius: var(--radius-chip); cursor: pointer; text-decoration: none;
}
.iconbtn:hover { background: var(--panel3); color: var(--ink); text-decoration: none; }

/* Round avatar button */
.avatar {
    width: 38px; height: 38px; border-radius: 50%; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: var(--panel3); border: none; color: #4a453f;
    background-size: cover; background-position: center; cursor: pointer;
    text-decoration: none; margin-left: .2rem;
}
.avatar:hover { background: var(--line); }

/* Content viewport - centered, internally scrolling per screen */
.content {
    position: relative; z-index: 1;
    flex: 1; min-height: 0; overflow: hidden;
    display: flex; flex-direction: column;
    width: 100%; max-width: 1560px; margin: 0 auto; padding: 1.15rem 1.5rem 1.5rem;
}
/* Screen wrapper that most pages use directly under .content */
/* Center a page's content on the Y axis when it is shorter than the viewport.
   `safe` falls back to top-alignment (no clipping) when content is taller, and a
   flex:1 child still fills, so full-height scrolling pages are unaffected. */
.screen { flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: safe center; }
.screen-scroll { flex: 1; min-height: 0; overflow-y: auto; padding-right: .25rem; }

/* ---------- Panels ---------- */
.panel {
    position: relative;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.25rem 1.4rem;   /* pages bleed dividers to the edge with margin:… -1.4rem */
    box-shadow: var(--shadow-card);
}
.panel > .toolpath-bg { display: none; }   /* old animated toolpath retired */
.panel-title {
    display: flex; align-items: center; gap: .55rem;
    font-weight: 700; font-size: 1rem; letter-spacing: -.01em; margin-bottom: .9rem;
}
.panel-title .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none; }

/* Hairline divider that bleeds to the panel edges (set horizontal margin inline) */
.hr { height: 1px; background: var(--hair); border: 0; margin: .85rem 0; }

.grid { display: grid; gap: 1.25rem; }
.grid-cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.grid-cols-2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) { .grid-cols-3, .grid-cols-2 { grid-template-columns: 1fr; } }

/* ---------- Buttons ---------- */
/* Primary is ink, not coral: the accent stays reserved for highlights. */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    border: none; border-radius: var(--radius-sm);
    padding: .62rem 1.2rem; font: inherit; font-weight: 700; font-size: .95rem;
    cursor: pointer; transition: background .15s ease, transform .08s ease;
    color: #fff; background: var(--ink-btn); white-space: nowrap;
}
.btn:hover { background: var(--ink-btn-hover); color: #fff; text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--ink-btn); }
.btn-grad { background: var(--ink-btn); color: #fff; }        /* legacy name, same ink CTA */
.btn-ghost { background: var(--panel); color: var(--ink); border: 1px solid var(--line); }
.btn-ghost:hover { background: var(--panel2); border-color: var(--line-strong); color: var(--ink); }
.btn-danger { background: var(--fil-red); color: #fff; }
.btn-danger:hover { background: #a83e26; }
.btn-block { width: 100%; }
.btn-sm { padding: .42rem .85rem; font-size: .84rem; }

/* Pill toggles (sorts, quality, steps, materials, tabs) */
.pill {
    display: inline-flex; align-items: center; gap: .35rem;
    border: 1px solid var(--line); background: var(--panel); color: #4a453f;
    border-radius: 999px; padding: .42rem .8rem; font: inherit; font-size: .82rem;
    font-weight: 600; white-space: nowrap; cursor: pointer;
}
.pill:hover { background: var(--panel2); border-color: var(--line-strong); }
.pill.active { background: var(--ink-btn); color: #fff; border-color: var(--ink-btn); }
.pill.ghost { background: transparent; border-color: transparent; color: var(--dim); }
.pill.ghost:hover { background: var(--panel2); }
.pill.ghost.active { background: var(--ink-btn); color: #fff; }

/* Sage "all good" pill (online, location attached) */
.pill-ok {
    display: inline-flex; align-items: center; gap: .4rem;
    font-size: .8rem; font-weight: 600; color: var(--ok-fg);
    background: var(--ok-bg); padding: .3rem .7rem; border-radius: 999px;
}
.pill-ok .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); flex: none; }

/* ---------- Forms ---------- */
label { display: block; font-weight: 600; font-size: .84rem; margin: 0 0 .3rem; color: var(--dim); }
input, select, textarea {
    width: 100%; background: var(--bg2); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: .6rem .75rem; font: inherit; font-size: .94rem;
}
input::placeholder, textarea::placeholder { color: #a7a29c; }
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--line-strong);
    box-shadow: 0 0 0 3px rgba(226,96,60,.12);
}
textarea { resize: vertical; min-height: 80px; }
input[type=range] { padding: 0; accent-color: var(--accent); box-shadow: none; }
input[type=checkbox], input[type=radio] { width: auto; box-shadow: none; accent-color: var(--accent); }
/* A radio inside a selected (ink) chip needs to invert, not stay browser-blue */
.chip.active input[type=radio], .chip.active input[type=checkbox] { accent-color: #fff; }
/* The native file control is the one widget that ignores the theme otherwise */
input[type=file] { padding: .42rem .5rem; font-size: .88rem; }
input[type=file]::file-selector-button {
    font: inherit; font-weight: 700; font-size: .84rem;
    margin-right: .6rem; padding: .35rem .8rem;
    border: 1px solid var(--line); border-radius: 9px;
    background: var(--panel3); color: var(--ink); cursor: pointer;
}
input[type=file]::file-selector-button:hover { background: var(--line); }

.field-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.field-row > * { flex: 1; min-width: 0; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.1rem; }

/* ---------- Chips / meta chips / tags ---------- */
.chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
    background: var(--panel); border: 1px solid var(--line);
    border-radius: 999px; padding: .42rem .8rem; font-size: .82rem; font-weight: 600; cursor: pointer;
    color: #4a453f; transition: background .12s ease, border-color .12s ease; white-space: nowrap;
}
.chip:hover { background: var(--panel2); border-color: var(--line-strong); color: var(--ink); }
.chip.active { background: var(--ink-btn); color: #fff; border-color: var(--ink-btn); }

/* Read-only meta chip (icon + label + value), used on order + spec views */
.metachip {
    display: inline-flex; align-items: center; gap: .4rem; min-width: 0; max-width: 100%;
    background: rgba(255,255,255,.92); border: 1px solid #eae6e1; border-radius: var(--radius-chip);
    padding: .4rem .7rem; font-size: .84rem; white-space: nowrap; color: var(--ink);
}
.metachip i { font-size: 1rem; color: #a19a92; flex: none; }
.metachip .k { color: var(--dim-3); font-size: .78rem; flex: none; }
.metachip b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.metachip.editable { cursor: pointer; transition: border-color .15s, background .15s; }
.metachip.editable:hover { border-color: var(--line-strong); background: #fff; }

/* Print-parameter chips fading up from the bottom of the 3D preview */
.spec-overlay {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    display: flex; flex-direction: column; gap: .55rem;
    padding: 1rem 1.1rem 1.1rem;
    background: linear-gradient(180deg, rgba(255,255,255,0), var(--shade) 28%);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
/* An inline editor takes the place of one chip, so it must not claim a whole row */
.spec-overlay .chips > input, .spec-overlay .chips > select { flex: 1 1 200px; width: auto; min-width: 0; }
.spec-overlay .chips > textarea { flex: 1 1 100%; }

.tag { display: inline-block; padding: .2rem .6rem; border-radius: 999px; font-size: .74rem; font-weight: 700; }
.tag-open { background: var(--t-open-bg); color: var(--t-open-fg); }
.tag-awarded { background: var(--t-awarded-bg); color: var(--t-awarded-fg); }
.tag-printing { background: var(--t-printing-bg); color: var(--t-printing-fg); }
.tag-ready { background: var(--t-ready-bg); color: var(--t-ready-fg); }
.tag-completed { background: var(--t-done-bg); color: var(--t-done-fg); }
.tag-cancelled { background: #f7ece9; color: var(--fil-red); }

/* Small coral rating badge */
.rating {
    display: inline-flex; align-items: center; gap: .25rem;
    font-size: .8rem; font-weight: 700; color: var(--coral-700);
    background: rgba(226,96,60,.12); border-radius: 999px; padding: .15rem .55rem;
}

/* ---------- Stat tiles ---------- */
.stats { display: flex; flex-wrap: wrap; gap: .75rem; }
.stat { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .6rem .9rem; min-width: 110px; }
.stat .v { font-size: 1.5rem; font-weight: 800; letter-spacing: -.03em; color: var(--ink); }
.stat .k { font-size: .76rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--dim-3); }
/* Borderless stat row (new-order footer) */
.stats-plain { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 1rem; }
.stats-plain .stat { background: transparent; border: 0; padding: 0; min-width: 0; }

/* ---------- Chat ---------- */
.chat { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.chat-log { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: .9rem; padding-right: .3rem; }
/* Head/foot carry the gutters when the chat fills a padding-less panel */
.chat-head { flex: none; display: flex; align-items: center; gap: .7rem; padding: 1.05rem 1.4rem; border-bottom: 1px solid var(--hair); }
.chat-foot { flex: none; display: flex; flex-direction: column; gap: .8rem; padding: 0 1.4rem 1.1rem; }
.chat-head + .chat-log { padding: 1.25rem 1.4rem; }
.msg { max-width: 82%; padding: .75rem .95rem; border-radius: 16px; font-size: .92rem; line-height: 1.55; }
.msg-ai { background: var(--panel2); color: var(--ink-2); align-self: flex-start; border-bottom-left-radius: 5px; }
.msg-user { background: #3a352f; color: #f8f6f3; align-self: flex-end; max-width: 78%; border-bottom-right-radius: 5px; }
.msg-ai-row { display: flex; align-items: flex-end; gap: .6rem; align-self: flex-start; max-width: 88%; }
.bot-ava {
    width: 28px; height: 28px; border-radius: 9px; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: #f5f0ec; color: var(--coral-700); border: none;
}
.bot-ava i { font-size: .95rem; }
.bot-ava.lg { width: 36px; height: 36px; border-radius: 12px; }
.bot-ava.lg i { font-size: 1.2rem; }

/* Offer to resume an unpublished upload (new order) */
.resume-card {
    display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
    padding: .8rem .9rem; border-radius: 14px;
    background: var(--coral-100); border: 1px solid var(--coral-300); color: var(--ink);
}

/* Composer: attach + text + send inside one rounded field */
.composer {
    display: flex; align-items: center; gap: .5rem;
    padding: .4rem .45rem .4rem 1rem;
    border: 1px solid var(--line); border-radius: 16px; background: var(--bg2);
}
.composer:focus-within { border-color: var(--line-strong); }
.composer input {
    flex: 1; min-width: 0; width: auto;
    border: none; outline: none; background: transparent; box-shadow: none;
    padding: .6rem 0; font-size: .94rem; color: var(--ink);
}
.composer input:focus { box-shadow: none; border: none; }
.composer .attach {
    width: 34px; height: 34px; flex: none; margin-left: -.55rem;
    display: flex; align-items: center; justify-content: center;
    border: none; border-radius: 10px; background: var(--panel3); color: #4a453f; cursor: pointer;
}
.composer .attach:hover { background: var(--line); }
.composer .send {
    width: 40px; height: 40px; flex: none;
    display: flex; align-items: center; justify-content: center;
    border: none; border-radius: 12px; background: var(--ink-btn); color: #fff; cursor: pointer;
}
.composer .send:hover { background: var(--ink-btn-hover); }
.composer .attach:disabled, .composer .send:disabled { opacity: .45; cursor: not-allowed; }
.chat-input { display: flex; gap: .5rem; margin-top: .6rem; }
.chat-input input { flex: 1; }
.typing-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--dim-3); display: inline-block; animation: blink 1.2s infinite; }

/* ---------- Cards / lists ---------- */
.card {
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1rem;
    box-shadow: var(--shadow-card);
    transition: border-color .15s ease;
}
.card:hover { border-color: var(--line-strong); }
.list { display: flex; flex-direction: column; gap: .75rem; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

/* Order card (4:3 tile: cover image + chip overlay) */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; align-content: start; }
.ocard {
    position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--line);
    background-color: var(--panel); color: var(--ink);
    background-image: repeating-linear-gradient(135deg, var(--hatch) 0 7px, transparent 7px 14px);
    box-shadow: var(--shadow-card);
    cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease;
}
.ocard:hover { border-color: var(--line-strong); box-shadow: 0 14px 32px -20px rgba(90,45,25,.55); }
.ocard .render {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .72rem; color: var(--dim-3);
}
.ocard .cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The only overlay on a card: chips (city + quote count) over the cover */
.ocard .ochips { position: absolute; left: .8rem; right: .8rem; bottom: .8rem; display: flex; flex-wrap: wrap; gap: .4rem; }
.ocard .ochip {
    display: inline-flex; align-items: center; gap: .3rem; min-width: 0;
    padding: .28rem .65rem; border-radius: 999px;
    background: rgba(255,255,255,.88); border: 1px solid #efece8;
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    font-size: .76rem; font-weight: 700; color: var(--ink); white-space: nowrap;
}
.ocard .ochip i { font-size: .9rem; color: #a19a92; flex: none; }
.ocard .ochip span { overflow: hidden; text-overflow: ellipsis; }
/* Quote count reads as the live signal, so it carries the accent */
.ocard .ochip.quotes { color: var(--coral-700); }
.ocard .ochip.quotes i { color: var(--coral); }
/* Dashed "new order" tile */
.ocard-new {
    aspect-ratio: 4 / 3; border: 1px dashed var(--line-strong); border-radius: var(--radius);
    background: rgba(255,255,255,.72); color: var(--dim);
    -webkit-backdrop-filter: var(--glass); backdrop-filter: var(--glass);
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .35rem;
    font: inherit; font-weight: 700; cursor: pointer;
}
.ocard-new:hover { border-color: var(--accent); color: var(--coral-600); background: var(--panel); }

/* Collapsible group header (my-orders / queue) - sits directly on the dark canvas */
.group-head {
    width: 100%; display: flex; align-items: center; gap: .7rem; margin-bottom: .8rem;
    background: transparent; border: none; padding: 0; font: inherit; color: inherit;
    cursor: pointer; text-align: left;
}
.group-head .label { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--on-bg-dim); white-space: nowrap; font-weight: 700; }
.group-head .count { font-size: .72rem; color: var(--on-bg-dim); }
.group-head .rule { flex: 1; height: 1px; background: rgba(255,255,255,.28); }

/* ---------- 3D preview region ---------- */
.viewer {
    width: 100%; border-radius: var(--radius-sm);
    background: var(--viewer); border: 1px solid var(--line);
}
.viewer-region {
    background: var(--viewer); color: var(--ink);
    display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden;
}
/* Floating file name + reload control over the preview */
.viewer-badge {
    position: absolute; top: .9rem; left: 1.1rem; z-index: 1;
    max-width: calc(100% - 4.5rem);
    display: inline-flex; align-items: center; gap: .45rem;
    font-size: .8rem; color: var(--dim-2);
    background: rgba(255,255,255,.8); border: 1px solid #efece8; border-radius: 999px;
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    padding: .3rem .7rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.viewer-badge b { color: var(--ink); font-weight: 700; }
.viewer-btn {
    position: absolute; top: .85rem; right: 1rem; z-index: 1;
    width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
    border: 1px solid #efece8; border-radius: 10px;
    background: rgba(255,255,255,.85); color: var(--dim); cursor: pointer;
}
.viewer-btn:hover { background: #fff; color: var(--ink); }

/* ---------- Portfolio gallery ---------- */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .75rem; }
.gallery img { width: 100%; height: 130px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); }

/* ---------- Modals ---------- */
.modal-backdrop {
    position: fixed; inset: 0; z-index: 85; display: flex; align-items: center; justify-content: center;
    padding: 1.5rem; background: rgba(30,26,22,.5);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.modal {
    width: min(460px, 100%); max-height: 100%; overflow-y: auto;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 30px 70px -30px rgba(60,30,18,.6);
    padding: 1.4rem 1.5rem;
}
.modal-title { display: flex; align-items: center; gap: .6rem; font-weight: 800; font-size: 1.05rem; letter-spacing: -.02em; }

/* ---------- Auth / home ---------- */
.auth-wrap { width: min(440px, 100%); margin: auto; }
.auth-wrap .panel { padding: 2rem; }
.alert {
    background: #fdeeea; border: 1px solid #f0c3b6; color: var(--coral-900);
    padding: .6rem .8rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .9rem;
}
.hero { text-align: center; padding: 2.5rem 1rem 1.5rem; }
.hero h1 { font-size: 2.8rem; }
.hero .sub { color: var(--on-bg); opacity: .85; font-size: 1.15rem; max-width: 620px; margin: .5rem auto 1.5rem; }

/* ---------- Image lightbox ---------- */
img.zoomable { cursor: zoom-in; }
.lightbox {
    position: fixed; inset: 0; z-index: 95;
    display: flex; align-items: center; justify-content: center; padding: 2rem;
    background: rgba(30,26,22,.8);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    cursor: zoom-out; animation: reveal .2s ease both;
}
.lightbox img { max-width: 100%; max-height: 100%; border-radius: 12px; box-shadow: 0 30px 70px -20px rgba(0,0,0,.7); }

/* ---------- Legal pages ---------- */
.panel.legal { width: min(780px, 100%); margin: 0 auto; }
.legal h1 { font-size: 1.6rem; }
.legal h2 { font-size: 1.05rem; margin: 1.5rem 0 .5rem; }
.legal p { line-height: 1.6; margin: .5rem 0; }
.legal ol, .legal ul { margin: .4rem 0 .8rem; padding-left: 1.4rem; display: flex; flex-direction: column; gap: .4rem; }
.legal li { line-height: 1.55; }

/* ---------- Cookie banner (injected by prntr.js) ---------- */
/* Pinned bottom-right as a toast: the bottom-centre of a screen is where the
   chat composer's upload button lives, and that must stay clickable. */
.cookie-bar {
    position: fixed; right: 1rem; bottom: 1rem; left: auto; z-index: 90;
    width: min(400px, calc(100vw - 2rem)); margin: 0;
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-float);
    padding: .9rem 1.1rem; font-size: .85rem;
    animation: reveal .4s ease both;
}
.cookie-bar .txt { flex: 1; min-width: 220px; color: var(--dim); }

/* ---------- Keyframes (template) ---------- */
@keyframes dashmove { to { stroke-dashoffset: -400; } }
@keyframes pulseRing { 0% { box-shadow: 0 0 0 0 var(--accent-a40); } 70% { box-shadow: 0 0 0 14px rgba(0,0,0,0); } 100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); } }
@keyframes justAdded { 0% { box-shadow: 0 0 0 0 rgba(226,96,60,.5); } 60% { box-shadow: 0 0 0 12px rgba(226,96,60,0); } 100% { box-shadow: 0 0 0 0 rgba(226,96,60,0); } }
@keyframes pointRight { 0%,100% { transform: translateX(0); opacity: .55; } 50% { transform: translateX(7px); opacity: 1; } }
@keyframes publishTease {
    0%,58%,100% { transform: translateY(0) scale(1) rotate(0deg); }
    64% { transform: translateY(-7px) scale(1.06) rotate(-3.5deg); }
    70% { transform: translateY(-3px) scale(1.04) rotate(3deg); }
    76% { transform: translateY(-6px) scale(1.05) rotate(-2deg); }
    84% { transform: translateY(0) scale(1.02) rotate(1deg); }
    92% { transform: translateY(0) scale(1) rotate(0deg); }
}
@keyframes nudgeX { 0%,100% { transform: translateX(0); } 50% { transform: translateX(-5px); } }
@keyframes reveal { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes rise { from { opacity: 0; } to { opacity: 1; } }
@keyframes blink { 0%,60%,100% { opacity: .25; } 30% { opacity: 1; } }

/* ---------- Blazor defaults ---------- */
.blazor-error-boundary { background: #b32121; padding: 1rem; color: white; border-radius: 12px; }
.blazor-error-boundary::after { content: "An error occurred."; }
.validation-message { color: var(--fil-red); font-size: .85rem; }
.text-danger { color: var(--fil-red); }
