/*
 * NEW-BCK-0180 §2. The customer portal skin.
 *
 * Codex's own block, transplanted from ~/Desktop/RICK-CODEX-PORTAL/portal.css:
 * Arial, compact spacing, square fields, slate section bars, lime primary
 * buttons, pale utility panels and dense tables. Every hex value below is his,
 * unchanged.
 *
 * WHAT IS OURS IS THE SCOPE. His file styles `html`, `body` and `*` directly,
 * which would have reskinned the back office the moment anything shared a
 * stylesheet. Everything here hangs off `.portal-skin`, stamped on the
 * storefront layout's own <body> and nowhere else, so the two buildings cannot
 * bleed into each other — the same rule 0179's <x-drop-zone> follows for the
 * same reason.
 *
 * No build step: this is plain CSS served from public/, exactly as
 * public/css/qc-screen.css is.
 */

.portal-skin {
    --slate: #3d4246;
    --slate2: #2f3438;
    --lime: #91bd18;
    --lime2: #71980d;
    --orange: #e6911f;
    --red: #b94135;
    --blue: #dcecf5;
    --line: #c5c9cc;
    --paper: #fff;
    --wash: #e9ebec;
    --muted: #72787c;
    --ink: #2d3235;

    /*
     * THE FOUR ROLES — NEW-BCK-0403 ruling 1, the owner's ruling of 24
     * September 2026, used the same way on every customer screen:
     *   GREEN  = place an order.
     *   BLUE   = request a quote.
     *   AMBER  = anything that needs the customer to act or answer.
     *   RED    = money owed.
     * Named aliases onto the hex values above (three of which — lime, blue,
     * orange/red — already carried exactly this meaning on one screen or
     * another); nothing here is a new colour, only a name that says what
     * each one is FOR, so a screen reaching for "the amber" cannot reach for
     * the wrong hex by accident. Colour is never the only signal — every
     * rule below keeps the words beside it.
     */
    --role-order: var(--lime);
    --role-order-dark: var(--lime2);
    --role-quote-bg: var(--blue);
    --role-quote-ink: #28536b;
    --role-attention-bg: #fde7bd;
    --role-attention-ink: #81540f;
    --role-attention-strong: var(--orange);
    --role-money: var(--red);

    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
    background: var(--wash);
    color: var(--ink);
}

.portal-skin * { box-sizing: border-box; }

/* ---- header + nav ---------------------------------------------------- */

.portal-skin .top { background: var(--slate2); border-bottom: 4px solid var(--lime); color: #fff; }
.portal-skin .top-inner { width: 1080px; max-width: calc(100% - 24px); margin: auto;
    display: flex; align-items: center; min-height: 48px; }
.portal-skin .brand { font-weight: bold; font-size: 18px; margin-right: 26px; }
.portal-skin .nav { display: flex; align-items: stretch; gap: 1px; }
.portal-skin .nav a,
.portal-skin .nav button { appearance: none; border: 0; background: transparent; color: #fff;
    text-decoration: none; padding: 16px 13px; font: inherit; cursor: pointer; }
.portal-skin .nav a:hover,
.portal-skin .nav a.active,
.portal-skin .nav button:hover { background: #4d5357; }
/* NEW-BCK-0416 C6 (U4) — the current page reads as current: an underline as
   well as the shade, and the "Place an order" dropdown's summary too. */
.portal-skin .nav a.active,
.portal-skin .nav details.active > summary { background: #4d5357; box-shadow: inset 0 -3px 0 var(--lime); }
.portal-skin .nav .signout { margin-left: 12px; }
.portal-skin .nav form { display: flex; margin: 0; }
/* NEW-BCK-0403 ruling 1 — BLUE: "Request a quote", wherever it appears,
   including this plain nav link — the same --role-quote-bg the dashboard's
   own quote button already wears (.button.secondary below), on a small
   pill so it reads against the dark nav bar rather than disappearing into
   the same white text as every other nav item. */
.portal-skin .nav a.nav-quote { background: var(--role-quote-bg); color: var(--role-quote-ink);
    margin: 8px 4px; padding: 8px 10px; border-radius: 3px; }
.portal-skin .nav a.nav-quote:hover,
.portal-skin .nav a.nav-quote.active { background: #c7e0ee; color: var(--role-quote-ink); }

/* NEW-BCK-0205 — V10. "New order", a product chooser rather than one
   hardcoded left-chest link — see layouts/storefront.blade.php's own note. */
.portal-skin .nav details { position: relative; }
.portal-skin .nav summary { list-style: none; padding: 16px 13px; cursor: pointer; }
.portal-skin .nav summary::-webkit-details-marker { display: none; }
.portal-skin .nav details:hover summary,
.portal-skin .nav details[open] summary { background: #4d5357; }
.portal-skin .nav details .menu { position: absolute; top: 100%; left: 0; min-width: 160px;
    background: var(--slate2); border: 1px solid #4d5357; z-index: 20; }
.portal-skin .nav details .menu a { display: block; padding: 10px 13px; white-space: nowrap; }

/* ---- page shell ------------------------------------------------------ */

.portal-skin .page { width: 1080px; max-width: calc(100% - 24px); margin: 16px auto 36px;
    background: var(--paper); border: 1px solid #b8bdc0; }
.portal-skin .page-title { background: var(--slate); color: #fff; padding: 10px 13px;
    display: flex; align-items: center; }
.portal-skin .page-title h1 { font-size: 18px; margin: 0; }
.portal-skin .page-title .ref { margin-left: auto; background: #272b2e; padding: 5px 8px; font-weight: bold; }
.portal-skin .section { border-top: 1px solid var(--line); }
.portal-skin .section:first-of-type { border-top: 0; }
.portal-skin .section-title { background: var(--slate); color: #fff; font-size: 13px;
    text-transform: uppercase; padding: 7px 10px; font-weight: bold; }
.portal-skin .body { padding: 12px; }
.portal-skin .footer-note { padding: 10px; background: #f1f2f2; border-top: 1px solid var(--line);
    font-size: 12px; color: #62686c; }

/* ---- order confirmation ---------------------------------------------- *\
   NEW-BCK-0228 §4. The page a customer lands on the moment they have
   committed to an order used to carry a `card` class this stylesheet has
   never defined, so it rendered as bare unstyled text on a grey background.
   Two rules, both in the skin's existing idiom: the four facts as a
   definition list, and the row holding "View your order" beside the quieter
   "Place another order".
\* ---------------------------------------------------------------------- */

.portal-skin dl.confirmation { margin: 0; display: grid; gap: 8px; }
.portal-skin dl.confirmation > div { display: grid; grid-template-columns: 150px 1fr; gap: 10px;
    align-items: baseline; }
.portal-skin dl.confirmation dt { font-weight: bold; color: #4a5054; }
.portal-skin dl.confirmation dd { margin: 0; }

.portal-skin .confirmation-actions { display: flex; align-items: center; gap: 14px;
    margin-top: 16px; flex-wrap: wrap; }
.portal-skin .confirmation-actions .button { font-size: 14px; padding: 10px 20px; }
.portal-skin .confirmation-actions .secondary { color: var(--slate); text-decoration: underline; }

@media (max-width: 620px) {
    .portal-skin dl.confirmation > div { grid-template-columns: 1fr; gap: 2px; }
}

/* ---- controls -------------------------------------------------------- */

.portal-skin .toolbar { display: grid; grid-template-columns: 1fr 180px 180px auto; gap: 8px;
    padding: 10px; background: #dfe2e3; border-bottom: 1px solid var(--line); }
/* NEW-BCK-0363 I3. The Orders toolbar carries more controls than the fixed
   four-column grid above was built for (search, Order type, From, To, Clear,
   Tickets shortcut, and an optional Just-mine checkbox) — a wrapping flex row
   fits any of that count without a second fixed template to keep in step. */
.portal-skin .orders-toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.portal-skin .orders-toolbar .orders-search { flex: 1 1 220px; max-width: 260px; }
.portal-skin .toolbar-field { display: flex; flex-direction: column; gap: 2px; font-size: 11px;
    font-weight: bold; color: #555; }
.portal-skin .toolbar-field input,
.portal-skin .toolbar-field select { font-weight: normal; }
.portal-skin input,
.portal-skin select,
.portal-skin textarea { font: inherit; border: 1px solid #aeb3b6; border-radius: 0;
    background: #fff; padding: 7px 8px; color: var(--ink); }
.portal-skin input,
.portal-skin select { height: 34px; }
.portal-skin textarea { width: 100%; min-height: 90px; resize: vertical; }
.portal-skin .button { display: inline-block; border: 1px solid var(--lime2);
    background: linear-gradient(#a9d62a, #83ad13); color: #fff; text-decoration: none;
    text-transform: uppercase; font-weight: bold; padding: 8px 13px; cursor: pointer; }
.portal-skin .button.orange { background: linear-gradient(#f1a43b, #d77a12); border-color: #b5660d; }
.portal-skin .button.red { background: linear-gradient(#d75c4d, #ad362d); border-color: #8f2c25; }
.portal-skin .button.dark { background: linear-gradient(#555c61, #363b3f); border-color: #282c2f; }
/* NEW-BCK-0416 C2 — "View quote" is BLUE on the orders list. */
.portal-skin .button.blue { background: linear-gradient(#4f8fd6, #2d6db5); border-color: #245a96; color: #fff; }
/* NEW-BCK-0403 ruling 1 — AMBER: a question needing the customer's own
   reply, never the green "place an order" colour a plain .button defaults
   to. "Reply to our question" and the dashboard's "View question" action
   both use this. */
.portal-skin .button.amber { background: linear-gradient(#f1c26b, #d9942a); border-color: #b5740d; color: #402c04; }
.portal-skin .button.small { font-size: 11px; padding: 6px 9px; }
/* NEW-BCK-0428C — the sign-in and create-account cards: centred, one
   column, every field full width. */
.portal-skin .page.auth-page { width: 460px; }
.portal-skin .auth-page label { display: block; margin: 12px 0 4px; font-weight: bold; }
.portal-skin .auth-page input[type=text],
.portal-skin .auth-page input[type=email],
.portal-skin .auth-page input[type=password] { width: 100%; box-sizing: border-box; }
.portal-skin .auth-page button[type=submit] { margin-top: 8px; }
/* NEW-BCK-0428C E2 — the corrected-version box and the closed earlier version. */
.portal-skin .corrected-ready .body { background: #eaf6dd; border-left: 4px solid #6f9d12; }
.portal-skin .corrected-ready-line { color: #3d6b00; font-size: 15px; margin: 0 0 8px; }
.portal-skin details.earlier-version { background: #f1f2f3; border: 1px solid #d5d8da; padding: 8px 10px; margin-top: 10px; color: #5f6266; }
.portal-skin details.earlier-version summary { cursor: pointer; font-weight: bold; }
.portal-skin .button.plain { background: #fff; color: var(--ink); border-color: #aeb3b6; }
.portal-skin .ready-actions .button { margin-right: 8px; }
/* NEW-BCK-0428C F4 — the contact line: the button, then the smaller way to reach us. */
.portal-skin .contact-line .contact-small { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
/* NEW-BCK-0428C F6 — a chosen upload: thumbnail or icon, name, Remove. */
.portal-skin .upload-chips { list-style: none; padding: 0; margin: 8px 0; }
.portal-skin .upload-chip { display: flex; align-items: center; gap: 8px; margin: 4px 0; }
.portal-skin .upload-chip-thumb { width: 48px; height: 48px; object-fit: contain; border: 1px solid #d5d8da; background: #fff; }
.portal-skin .upload-chip-icon { font-size: 28px; width: 48px; text-align: center; }
.portal-skin .upload-chip-remove { color: #ad362d; }
/* NEW-BCK-0428C F7 — the "Loading…" pill. */
.portal-skin .page-loading { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 1000;
    background: #363b3f; color: #fff; padding: 6px 14px; border-radius: 14px; font-size: 13px; }
.portal-skin .page-loading[hidden] { display: none; }
/* NEW-BCK-0428C — a file button shows the file's name in its real case. */
.portal-skin .button.file-button { text-transform: none; }
.portal-skin .button[disabled] { opacity: .55; cursor: default; }
/* NEW-BCK-0353-CUSTOMER-PORTAL-A. FRONTEND-SPEC.md §2: "Pale neutral
   secondary; pale blue Request a quote; not every button lime." Place a new
   order keeps the lime primary above; Request a quote and the dashboard's
   product buttons use this. */
.portal-skin .button.secondary { background: var(--blue); color: var(--slate2);
    border-color: #b7d3e3; text-transform: none; font-weight: normal; }

/* ---- dashboard --------------------------------------------------------- */

.portal-skin .dashboard-actions { display: flex; gap: 10px; margin: 10px 0; flex-wrap: wrap; }
.portal-skin .product-buttons { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 16px; }
.portal-skin .product-button { display: inline-block; background: #fff; border: 1px solid var(--line);
    color: var(--ink); text-decoration: none; font-weight: bold; padding: 10px 16px; }
.portal-skin .product-button:hover { border-color: var(--lime2); background: #f4f7eb; }

/* ---- buckets + order table ------------------------------------------- */

/* NEW-BCK-0363 I4/I7: Orders now has six scopes and Tickets three, not a
   fixed four — auto-fit keeps every row of buttons even-width without a
   second grid template per screen. */
.portal-skin .buckets { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 5px; padding: 10px; background: #f5f6f6; }
.portal-skin .bucket { display: block; background: #d9dcde; color: #333; text-decoration: none;
    border: 1px solid #b9bdc0; padding: 9px 10px; font-weight: bold; }
.portal-skin .bucket.active { background: var(--lime); border-color: var(--lime2); color: #fff; }
.portal-skin .bucket span { float: right; background: rgba(0, 0, 0, .15); padding: 1px 5px; }
/* NEW-BCK-0403 ruling 1 — AMBER: "Awaiting your response" is one of the
   named AMBER cases, drawn only while it actually holds something (an empty
   tab needs no attention). Overrides both the plain and the active bucket
   background above. */
.portal-skin .bucket-attention { background: var(--role-attention-bg); border-color: #e6c98a; color: var(--role-attention-ink); }
.portal-skin .bucket-attention.active { background: var(--role-attention-strong); border-color: #b5740d; color: #fff; }
.portal-skin .orders { width: 100%; border-collapse: collapse; }
.portal-skin .orders th { background: #60666a; color: #fff; text-align: left; padding: 7px 8px; font-size: 12px; }
.portal-skin .orders td { border-bottom: 1px solid #d3d6d8; padding: 7px 8px; vertical-align: middle; }
.portal-skin .orders tr:hover td { background: #f4f7eb; }
/* NEW-BCK-0259 TASK C. An invoice's lines are sorted by date and may cover ten
   orders; a heavier rule above the first row of each new one is what "several
   orders clearly separated" looks like on a screen. */
.portal-skin .invoice-lines tr.order-break td { border-top: 2px solid #9aa2a6; }
.portal-skin .thumb { width: 58px; height: 45px; border: 1px solid #aeb3b6;
    background: linear-gradient(135deg, #e1e3e4 25%, #c6c9cb 25%, #c6c9cb 50%, #e1e3e4 50%, #e1e3e4 75%, #c6c9cb 75%);
    background-size: 16px 16px; display: flex; align-items: center; justify-content: center;
    color: #666; font-size: 10px; overflow: hidden; }
.portal-skin .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- status chips ---------------------------------------------------- */

.portal-skin .status { display: inline-block; padding: 4px 7px; background: #d9dcde;
    font-size: 11px; font-weight: bold; text-transform: uppercase; }
.portal-skin .status.progress { background: #dcecf5; color: #28536b; }
.portal-skin .status.approval { background: #fde7bd; color: #81540f; }
.portal-skin .status.hold { background: #f3d5d0; color: #7f2e27; }
.portal-skin .status.complete,
.portal-skin .status.paid { background: #dceab7; color: #46620c; }
.portal-skin .status.unpaid { background: #f4d0cb; color: #8a2e26; }
/* NEW-BCK-0205 — V5. Grey, not red: a decline is a completed decision, not a fault. */
.portal-skin .status.cancelled { background: #d9dcde; color: #4a4f57; }

/* ---- the four colour roles — NEW-BCK-0403 ruling 1 ------------------- */

/* AMBER — "1 new reply", beside the Tickets nav tab and the dashboard's own
   shortcut, and any other "this needs you" badge added later. */
.portal-skin .badge-attention { display: inline-block; margin-left: 6px; padding: 2px 6px;
    background: var(--role-attention-strong); color: #fff; font-size: 10px; font-weight: bold;
    text-transform: uppercase; letter-spacing: .02em; border-radius: 3px; vertical-align: middle; }

/* RED — money owed. Plain grey at zero (the surrounding element's own
   colour, unchanged) is the absence of this class, never a class of its
   own — there is nothing to add contrast against at zero. */
.portal-skin .text-money { color: var(--role-money); font-weight: bold; }

/* NEW-BCK-0401 finding 1 — the small "Quote" tag beside a row's reference. */
.portal-skin .tag.quote-tag { display: inline-block; padding: 2px 6px; margin-left: 4px;
    background: #e6d9f5; color: #4a2a75; font-size: 10px; font-weight: bold;
    text-transform: uppercase; border-radius: 3px; }

/* ---- detail ---------------------------------------------------------- */

.portal-skin .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.portal-skin .details { width: 100%; border-collapse: collapse; }
.portal-skin .details th,
.portal-skin .details td { padding: 6px 8px; border-bottom: 1px solid #d6d9da; text-align: left; }
.portal-skin .details th { width: 42%; background: #f1f2f2; color: #555; }
.portal-skin .file-list { list-style: none; padding: 0; margin: 0; }
.portal-skin .file-list li { display: flex; gap: 8px; align-items: center; padding: 7px;
    border-bottom: 1px solid #ddd; }
.portal-skin .preview-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 12px; }
.portal-skin .imagebox { height: 320px; border: 1px solid #afb4b7; background: #eef0f1;
    display: flex; align-items: center; justify-content: center; text-align: center;
    color: #6d7377; font-weight: bold; overflow: hidden; }
.portal-skin .imagebox img { max-width: 100%; max-height: 100%; object-fit: contain; }
.portal-skin .imagebox.sewout { height: 230px; background: #e2e5e6; }
/* NEW-BCK-0432 T1 — the same checkerboard behind a transparent PNG as every
   staff screen (resources/views/components/layouts/app.blade.php's own
   .preview-checkered), so a customer's own transparent upload is visible
   here too, not just to staff. */
.portal-skin .preview-checkered { background-color: #f4f4f5; background-image:
    linear-gradient(45deg, #ddd 25%, transparent 25%), linear-gradient(-45deg, #ddd 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #ddd 75%), linear-gradient(-45deg, transparent 75%, #ddd 75%);
    background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0; }
.portal-skin .download-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.portal-skin .ticket-strip { background: var(--blue); border: 1px solid #a9c6d7; padding: 9px 10px; }
/* NEW-BCK-0403 ruling 1 — AMBER: a live ticket that is waiting on the
   CUSTOMER to answer (App\Models\Ticket::isWaitingOnUs() false) is exactly
   the "questions to them" case; one already answered and waiting on us
   stays the plain blue box above. */
.portal-skin .ticket-strip-attention { background: var(--role-attention-bg); border-color: #e6c98a; color: var(--role-attention-ink); }
.portal-skin .quote { font-size: 24px; font-weight: bold; color: #435d08; }
.portal-skin .approval-actions { display: flex; gap: 8px; margin-top: 12px; }
.portal-skin .locked { border: 2px solid var(--orange); background: #fff4df; padding: 12px;
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.portal-skin .locked strong { font-size: 16px; }

/* ---- invoices, tickets, account -------------------------------------- */

.portal-skin .invoice-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.portal-skin .metric { background: #eef0f1; border: 1px solid #c7cbcd; padding: 12px; }
.portal-skin .metric b { display: block; font-size: 20px; margin-top: 4px; }
.portal-skin .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.portal-skin .thread { border: 1px solid var(--line); }
.portal-skin .message { padding: 10px; border-bottom: 1px solid var(--line); }
.portal-skin .message.customer { background: #f5f7ec; }
.portal-skin .message.support { background: #e8f2f7; }
.portal-skin .message .meta { font-size: 11px; color: var(--muted); margin-bottom: 5px; }
.portal-skin .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.portal-skin .field label { display: block; font-weight: bold; color: #555; margin: 0 0 4px; }
.portal-skin .field input,
.portal-skin .field select,
.portal-skin .field textarea { width: 100%; }
.portal-skin .hint { font-size: 11px; color: var(--muted); }
.portal-skin .right { text-align: right; }
.portal-skin .empty-preview { color: #777; font-style: italic; }
.portal-skin .priority { color: #8a570b; font-weight: bold; }

/* Ours: the messages the skin has no block for. Same palette. */
.portal-skin .flash { background: #dceab7; border: 1px solid #a9c46a; color: #3c5409; padding: 9px 10px; margin: 0 0 10px; }
.portal-skin .notice { background: #fdf3e0; border: 1px solid #e6c98a; color: #6f4a06; padding: 9px 10px; }
.portal-skin .error { background: #f4d0cb; border: 1px solid #d09a92; color: #7f2620; padding: 9px 10px; margin: 0 0 10px; }
.portal-skin .field-error { color: var(--red); font-size: 12px; margin: 4px 0 0; }

@media (max-width: 760px) {
    .portal-skin .top-inner { display: block; padding-top: 8px; }
    .portal-skin .brand { display: block; margin: 0 8px 6px; }
    .portal-skin .nav { overflow-x: auto; }
    .portal-skin .nav a,
    .portal-skin .nav button { white-space: nowrap; padding: 11px 10px; }
    .portal-skin .toolbar,
    .portal-skin .detail-grid,
    .portal-skin .preview-grid,
    .portal-skin .two-col,
    .portal-skin .form-grid,
    .portal-skin .invoice-summary { grid-template-columns: 1fr; }
    .portal-skin .buckets { grid-template-columns: 1fr 1fr; }
    .portal-skin .orders { font-size: 12px; }
    .portal-skin .orders .optional { display: none; }
    .portal-skin .page { max-width: 100%; margin: 0; }
    .portal-skin .imagebox { height: 230px; }
}

/* ---------------------------------------------------------------------------
   NEW-BCK-0206 §8 — the money strip.

   MONEY-DECISIONS-v1 R11's tone has a visual half. The paused state is a quiet
   amber band, not a red alarm: the customer is being told a fact and given an
   action, and a page that shouts at somebody who owes £11 for two edits is the
   opposite of what the ruling asks for.
   --------------------------------------------------------------------------- */
/* NEW-BCK-0368 P9. Row, not column — the same one-line shape .account-card
   already has (below): the figures on the left, the one control pushed
   right by `.money-strip .button`'s own margin-left: auto, wrapping only
   where the width forces it (narrow screens, or a long overdue line). The
   column layout used to drop the button to its own row on every desktop
   render that had money to show at all. */
.portal-skin .money-strip { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem;
  padding: .7rem .9rem; margin-bottom: 1rem;
  border: 1px solid #dfe3e8; border-radius: 8px; background: #fbfcfd; }
.portal-skin .money-strip-paused { border-color: #e6c98a; background: #fdf8ee; }
/* NEW-BCK-0328 R2 — one class per named state. Neutral is the plain strip;
   paused is the amber it has always been; overdue is urgent and says so. */
.portal-skin .money-strip-neutral { border-color: #d9dde3; background: #fbfcfd; }
.portal-skin .money-strip-urgent { border-color: #d9534f; background: #fdf3f3; }
.portal-skin .money-strip-urgent .money-strip-line { color: #8a2b28; font-weight: 600; }
.portal-skin .money-strip-figures { display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem; }
.portal-skin .money-metric { display: flex; flex-direction: column; line-height: 1.25; }
.portal-skin .money-metric .money-k { font-size: .72rem; letter-spacing: .02em; text-transform: uppercase; color: #7b8794; }
.portal-skin .money-metric b { font-size: 1.05rem; color: #2c3038; }
.portal-skin .money-strip-line { font-size: .95rem; color: #2c3038; }
.portal-skin .money-strip-line b { font-weight: 600; }
.portal-skin .money-strip-note { margin: 0; max-width: 62ch; color: #6b5a2e; font-size: .92rem; }
.portal-skin .money-strip .button { margin-left: auto; }

/* ---------------------------------------------------------------------------
   NEW-BCK-0333 — the account card. R5's four facts, quietly laid out; the
   same restrained tone as the money strip above rather than a second alarm.
   --------------------------------------------------------------------------- */
.portal-skin .account-card { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem;
  padding: .7rem .9rem; margin-bottom: 1rem;
  border: 1px solid #dfe3e8; border-radius: 8px; background: #fbfcfd; }
.portal-skin .account-card-row { font-size: .92rem; color: #2c3038; }
/* NEW-BCK-0363 I2 — the account reference, drawn in every strip state. */
.portal-skin .account-card-ref,
.portal-skin .money-strip .account-card-ref { font-size: .8rem; font-weight: 600; color: #6b7280;
  text-transform: uppercase; letter-spacing: .02em; }
.portal-skin .account-card-row-overdue { color: #7a4d16; }
.portal-skin .account-card-note { margin: 0; color: #6b5a2e; font-size: .92rem; }
.portal-skin .account-card .button { margin-left: auto; }

/* ---------------------------------------------------------------------------
   NEW-BCK-0214 §3 — the storefront footer.

   It exists to carry two links and it should look like it: a hairline rule, a
   quiet row, and no visual weight competing with the page above it. The rule
   is the same --line the rest of the shell uses rather than a second grey, and
   the row sits on the same 1080px measure as .top-inner so the links land
   under the nav they belong with rather than at the edge of the window.
   --------------------------------------------------------------------------- */
.portal-skin .foot { margin-top: 2.5rem; border-top: 1px solid var(--line); background: #f7f8f8; }
.portal-skin .foot-inner { width: 1080px; max-width: calc(100% - 24px); margin: auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .6rem 1.4rem; padding: 1rem 0; font-size: .86rem; color: #6b7280; }
.portal-skin .foot nav { display: flex; flex-wrap: wrap; gap: 1.1rem; }
.portal-skin .foot a { color: #4b5563; text-decoration: none; border-bottom: 1px solid transparent; }
.portal-skin .foot a:hover { color: #1f2937; border-bottom-color: currentColor; }

@media (max-width: 720px) {
  .portal-skin .foot-inner { justify-content: flex-start; }
}

/*
 * NEW-BCK-0241 TASK C. THE EDIT MARK, ON THE CUSTOMER'S SIDE.
 *
 * The owner's ruling reaches the customer's own order list and order page, and
 * the portal loads none of the back office's tokens — so <x-edit-mark>'s
 * `badge badge-edit` classes mean nothing here and the mark would render as
 * bare text. Its own hook, painted in the portal's own blue.
 */
.portal-skin .edit-mark { display: inline-block; padding: 3px 6px; border-radius: 3px;
    background: #dcecf5; color: #28536b; font-size: 10px; font-weight: bold;
    letter-spacing: .05em; vertical-align: middle; }
.portal-skin .edit-mark-parent { font-size: 11px; color: var(--muted); }

/*
 * NEW-BCK-0299 R4 — THE LEGAL PAGES, rendered from markdown.
 *
 * The portal's skin styles the screens it was written for — cards, tables,
 * fields — and none of those is a six-thousand-word document. Markdown emits
 * h1/h2/ul/em/strong straight into `.body`, where nothing had a rule, so
 * without these a terms page renders as one undifferentiated wall with its
 * headings the same size as its paragraphs. Scoped to `.legal` so no other
 * screen's `.body` changes.
 *
 * MEASURE, not width: a line of legal text longer than about 70 characters is
 * one people lose their place in, which is the practical difference between
 * terms that are published and terms that are read.
 */
.portal-skin .legal { max-width: 42rem; line-height: 1.6; }
.portal-skin .legal h1 { font-size: 1.5rem; margin: 0 0 1rem; }
.portal-skin .legal h2 { font-size: 1.15rem; margin: 1.75rem 0 .5rem; }
.portal-skin .legal h3 { font-size: 1rem; margin: 1.5rem 0 .5rem; }
.portal-skin .legal p { margin: 0 0 1rem; }
.portal-skin .legal ul, .portal-skin .legal ol { margin: 0 0 1rem 1.25rem; padding: 0; }
.portal-skin .legal li { margin: 0 0 .35rem; }
.portal-skin .legal code { background: #f3f4f6; padding: 1px 4px; border-radius: 3px; font-size: .9em; }
.portal-skin .legal hr { border: 0; border-top: 1px solid #e5e7eb; margin: 1.75rem 0; }
.portal-skin .legal a { color: #28536b; }

/* R4's order-form line, beside Place order and never in place of it. */
.portal-skin .legal-consent { margin: 0 0 .5rem; font-size: .9rem; }

/* ---- the order list's pager — NEW-BCK-0312 ----------------------------
   x-floor-pager is the floor's footer, reused whole rather than copied, and
   the floor's stylesheet calls its buttons `.btn` while this skin calls its
   own `.button`. Rather than fork the component for one class name, the two
   names are made to mean the same thing here. Nothing else on the storefront
   uses `.btn`, so this is scoped to the pager and cannot reach a form. */
.portal-skin .pager-row { margin-top: .9rem; }
.portal-skin .floor-pager-count { font-size: 12px; color: var(--muted); }
.portal-skin .floor-pager-nav { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.portal-skin .floor-pager-nav .btn { display: inline-block; border: 1px solid var(--lime2);
    background: linear-gradient(#a9d62a, #83ad13); color: #fff; text-decoration: none;
    text-transform: uppercase; font-weight: bold; font-size: 11px; padding: 6px 9px; cursor: pointer; }
.portal-skin .floor-pager-nav .btn[disabled] { opacity: .55; cursor: default; }
.portal-skin .floor-pager-nav .muted { font-size: 11px; color: var(--muted); text-transform: uppercase; }

/* ---------------------------------------------------------------------------
   NEW-BCK-0354-CUSTOMER-PORTAL-B — the rebuilt Dashboard (W1-W7).

   .panel reuses the same restrained card look the money strip and the
   account card already established (border, radius, pale background) rather
   than inventing a second visual language for Welcome/Get in touch/Account
   details/Support — FRONTEND-SPEC.md §2's "no oversized headings/cards".
   --------------------------------------------------------------------------- */
.portal-skin .dashboard-title { display: block; }
.portal-skin .dashboard-title h1 { display: block; }
.portal-skin .panel { border: 1px solid #dfe3e8; border-radius: 8px; background: #fbfcfd;
    padding: .7rem .9rem; margin-bottom: 1rem; }
.portal-skin .panel-title { font-weight: bold; font-size: .95rem; margin-bottom: .3rem; color: #2c3038; }
.portal-skin .dashboard-intro { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
.portal-skin .dashboard-intro .panel p { margin: 0 0 .5rem; font-size: .92rem; }

.portal-skin .tickets-shortcut { display: flex; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: 2px;
    background: #fff; border: 1px solid #aeb3b6; padding: 7px 8px; text-decoration: none;
    color: var(--ink); font-size: .9rem; white-space: nowrap; }
.portal-skin .tickets-shortcut:hover { border-color: var(--lime2); background: #f4f7eb; }

/* NEW-BCK-0368 P5. Six tabs, not five — NEW-BCK-0365 D1 prepended "All" to
   Dashboard::SCOPES and this rule was never updated, so the sixth tab
   ("Recently completed edits") wrapped onto a lonely second row at desktop
   width. The bucket grid's own column count widens to match, and the
   tighter padding/font keep six labels — the longest being "Recently
   completed edits" — on one row instead of forcing a narrower screen's fix
   onto a desktop one. */
.portal-skin .dashboard-scopes { grid-template-columns: repeat(6, 1fr); }
.portal-skin .dashboard-scopes .bucket { padding: 8px 6px; font-size: .82rem; }

.portal-skin .product-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 8px 0 16px; }
.portal-skin .product-tile { display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
    background: #fff; border: 1px solid var(--line); color: var(--ink); text-decoration: none;
    padding: 12px 14px; }
.portal-skin .product-tile:hover { border-color: var(--lime2); background: #f4f7eb; }
.portal-skin .product-tile-icon { color: var(--slate2); }
.portal-skin .product-tile-label { font-weight: bold; }
.portal-skin .product-tile-description { font-size: .82rem; color: var(--muted); }

/* NEW-BCK-0368 P6 — a short set of cards, side by side, not a second copy
   of the ten-row orders list above. auto-fit rather than a fixed column
   count: three cards side by side at desktop width, fewer as the window
   narrows, one per row on a phone. */
.portal-skin .completed-cards { display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: .8rem; margin-bottom: 1rem; }
.portal-skin .completed-cards .completed-download-row { margin-bottom: 0; flex-direction: column;
    align-items: stretch; justify-content: flex-start; }
.portal-skin .completed-download-row { display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: .6rem; }
.portal-skin .completed-download-row p { margin: 0; }
.portal-skin .completed-download-heading { display: flex; align-items: center; gap: .6rem; }
.portal-skin .download-buttons { display: flex; flex-wrap: wrap; gap: 6px; }
.portal-skin .section-title { display: flex; align-items: center; justify-content: space-between; }
.portal-skin .section-title-link { color: #fff; font-size: .78rem; font-weight: normal;
    text-transform: none; text-decoration: underline; }

.portal-skin .dashboard-footer-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1rem; }

@media (max-width: 760px) {
    .portal-skin .dashboard-intro,
    .portal-skin .dashboard-footer-panels { grid-template-columns: 1fr; }
    .portal-skin .dashboard-scopes { grid-template-columns: 1fr 1fr; }
    .portal-skin .product-tiles { grid-template-columns: 1fr 1fr; }
    .portal-skin .dashboard-orders .optional { display: none; }
}

/*
    NEW-BCK-0364B F7 — <x-annotate>/<x-annotated>'s own styling, missing from
    this shell before now (NEW-BCK-0356C found and disclosed the gap; this is
    the customer order and edit forms' own copy of App\Support\Annotations'
    four marks, the same rules components/layouts/app.blade.php already
    carries for the back-office screens). Unscoped, like the shared component
    itself — this markup is never nested under .portal-skin.
*/
.annotated-frame { position: relative; display: inline-block; max-width: 100%;
    line-height: 0; border: 1px solid var(--line, #c5c9cc); border-radius: 4px; background: #fbfcfd; }
.annotated-frame img { display: block; max-width: 100%; height: auto; }
.annotated-box { position: absolute; border: 2px solid #e11d48; border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(255,255,255,.7) inset; pointer-events: none; }
.annotated-n { display: inline-block; min-width: 1.25rem; height: 1.25rem; line-height: 1.25rem;
    text-align: center; border-radius: 999px; background: #e11d48; color: #fff;
    font-size: .72rem; font-weight: 700; }
.annotated-box .annotated-n { position: absolute; top: -.65rem; left: -.65rem; }
.annotated-notes { list-style: none; margin: .6rem 0 0; padding: 0; line-height: 1.45; }
.annotated-notes li { display: flex; gap: .45rem; align-items: center;
    margin-bottom: .35rem; font-size: .88rem; }
.annotate-frame { cursor: crosshair; touch-action: none; user-select: none; }
.annotate-box { pointer-events: auto; cursor: move; background: rgba(225,29,72,.08); }
.annotate-grip { position: absolute; right: -5px; bottom: -5px; width: 12px; height: 12px;
    background: #e11d48; border: 2px solid #fff; border-radius: 2px; cursor: nwse-resize; }
.annotated-lines { z-index: 1; }
.annotated-pin, .annotated-badge { position: absolute; transform: translate(-50%, -50%);
    pointer-events: none; z-index: 2; }
.annotate-type { font-size: .74rem; color: var(--muted, #72787c); text-transform: uppercase; letter-spacing: .03em; }
.annotate-toolbar { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 .6rem; }
.annotate-toolbar button { border: 1px solid var(--line, #c5c9cc); background: #fff; padding: 5px 10px;
    font-size: .82rem; cursor: pointer; border-radius: 3px; }
.annotate-toolbar button[aria-pressed="true"] { background: #e11d48; border-color: #e11d48; color: #fff; }

/* NEW-BCK-0428B P1 — the one Pay control is a POST form; keep it inline. */
.portal-skin .pay-all-form { display: inline-block; margin: 0; }

/* NEW-BCK-0446 PART B — site announcements: a slim banner, or a dashboard card. */
.announcement { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem;
    padding: .6rem .9rem; border-bottom: 1px solid var(--line, #c5c9cc); }
.announcement-banner { border-radius: 0; }
.announcement-card { border: 1px solid var(--line, #c5c9cc); border-radius: 4px; margin: 0 0 1rem; }
.announcement-info { background: #eef6fb; }
.announcement-warning { background: #fdf3e3; }
.announcement p { margin: .2rem 0 0; }
.announcement button { background: none; border: none; font-size: 1.1rem; line-height: 1; cursor: pointer; }
