/* ============================================================
   PROFESSIONAL STOREFRONT — V13-8 Step 2
   /store/{handle}   ·   built to the build-reference mockups

   ONE static file: the 10 palettes as [data-theme] blocks, plus every
   component that consumes them. Static and cacheable on purpose — the
   reader is a bride opening a WhatsApp forward on mobile data, and a
   nonce'd inline <style> per request would defeat the CDN cache on the
   one surface we most need to be fast.

   TYPE SYSTEM (from the mockups):
     Playfair Display  — names, prices, section titles. The editorial voice.
     DM Sans           — body.
     JetBrains Mono    — kickers, counts, money-adjacent metadata.

   PALETTE VALUES are lifted verbatim from the curation mockup's PALETTES
   array, so what she picks in the theme picker is exactly what renders.

   MOBILE-FIRST. Desktop is the enhancement.
   ============================================================ */

/* ── PALETTES ─────────────────────────────────────────────────
   --sf-deep    her primary: headings, name, section titles
   --sf-accent  her gold: prices, CTA, kickers
   --sf-bg      page (ivory)
   --sf-soft    tinted fill: chips, hero wash, featured plan
   --sf-line    hairlines
   --sf-ink     body text
   --sf-muted   secondary text
   ───────────────────────────────────────────────────────────── */

[data-theme="blush"]     { --sf-deep:#8a5560; --sf-accent:#b8892e; --sf-bg:#faf5ef; --sf-soft:#f5e2e5; --sf-line:#eddcde; --sf-ink:#3a3238; --sf-muted:#9a8a8e; }
[data-theme="noir"]      { --sf-deep:#1f1d22; --sf-accent:#c9a24b; --sf-bg:#f7f3ec; --sf-soft:#efe6d6; --sf-line:#e6ddcf; --sf-ink:#2a2730; --sf-muted:#8b8579; }
[data-theme="esmeralda"] { --sf-deep:#1a5c47; --sf-accent:#c2a35a; --sf-bg:#f2f7f3; --sf-soft:#d9ecdf; --sf-line:#d6e6da; --sf-ink:#263a30; --sf-muted:#7f9488; }
[data-theme="rose"]      { --sf-deep:#9c6a6f; --sf-accent:#c98f6a; --sf-bg:#faf5f1; --sf-soft:#f0e2da; --sf-line:#ecdfd8; --sf-ink:#3a302e; --sf-muted:#9c8a83; }
[data-theme="oceano"]    { --sf-deep:#14545c; --sf-accent:#3fa3ac; --sf-bg:#eef6f6; --sf-soft:#d3ebec; --sf-line:#d2e6e7; --sf-ink:#23383a; --sf-muted:#7a9497; }
[data-theme="terracota"] { --sf-deep:#a34e2f; --sf-accent:#d9944e; --sf-bg:#faf3ea; --sf-soft:#f4ddc7; --sf-line:#ecdcc9; --sf-ink:#3d2b22; --sf-muted:#9c8574; }
[data-theme="lavanda"]   { --sf-deep:#5e3d75; --sf-accent:#a98fc9; --sf-bg:#f6f2fa; --sf-soft:#e7ddf1; --sf-line:#e2d6ee; --sf-ink:#322a3a; --sf-muted:#8b8296; }
[data-theme="vino"]      { --sf-deep:#6e2436; --sf-accent:#b8892e; --sf-bg:#f8f1ee; --sf-soft:#eed9d6; --sf-line:#ecd7d3; --sf-ink:#35262a; --sf-muted:#9a8489; }
[data-theme="pizarra"]   { --sf-deep:#2b3a4a; --sf-accent:#a8794e; --sf-bg:#f4f6f8; --sf-soft:#dde5ec; --sf-line:#dde4ea; --sf-ink:#26303a; --sf-muted:#8090a0; }
[data-theme="miel"]      { --sf-deep:#9a5a12; --sf-accent:#d99a3a; --sf-bg:#fbf4e8; --sf-soft:#f6e6c9; --sf-line:#efe1c8; --sf-ink:#3a2e1e; --sf-muted:#9a8a70; }

:root {
    --sf-disp: 'Playfair Display', Georgia, serif;
    --sf-body: 'DM Sans', system-ui, -apple-system, sans-serif;
    --sf-mono: 'JetBrains Mono', ui-monospace, monospace;
    --sf-green: #1a7a50;
}

* { box-sizing: border-box; }

/* 🔴 [hidden] MUST WIN. The `hidden` attribute is only honoured by the BROWSER's
   stylesheet, and ANY author rule beats a UA rule — so the moment a component
   with `hidden` on it also has `display:flex` in this file, `hidden` silently
   stops working. That is exactly what greyed out the whole storefront: .sf-lb
   (the lightbox) is a fixed full-screen scrim with display:flex, so it rendered
   over the page permanently and nothing was clickable. The 60 hidden catalogue
   cards (.sf-prod, also flex) were showing for the same reason.
   One rule, at the top, so this can never recur for the next hidden component. */
[hidden] { display: none !important; }

.sf-page {
    margin: 0;
    background: var(--sf-bg);
    color: var(--sf-ink);
    font-family: var(--sf-body);
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
}
/* CD-68 — footer pin, STOREFRONT INDEX ONLY (the `sf-page--store` body class).
   🔴 The product-detail page and the hero editor's nested .sf-page preview must
   NOT become flex columns — that is what was distorting the product layout. */
body.sf-page--store {
    display: flex;
    flex-direction: column;
}

/* ── HERO ───────────────────────────────────────────────────── */
.sf-hero {
    background: linear-gradient(135deg, var(--sf-soft), var(--sf-bg));
    border-bottom: 1px solid var(--sf-line);
    padding: 16px 18px;
    /* Anchors .vf-me (the viewer badge) to this band's top-right corner. */
    position: relative;
}

/* ══ VIEWER BADGE — "who am I signed in as" ════════════════════════════
   Pinned to the top-right of whatever band it is dropped into, floating
   over her hero photography. It answers one question and only appears for
   signed-in, non-guest users (the component renders nothing otherwise).

   It has to survive being placed over ANY image — a white headshot, a dark
   salon, a bright beach. Hence the ring AND the drop shadow: the ring gives
   it an edge against dark photos, the shadow gives it one against light. A
   border alone disappears on half the storefronts in the catalogue. */
.vf-me {
    position: absolute;
    /* Inset properly, not wedged against the corner. At 12/14 it read as
       something that had slipped off the edge rather than something placed —
       and on a phone it collided with the card's own rounded corner. */
    top: 20px; right: 22px;
    z-index: 6;                  /* above .sf-tile images, below the drawer */
    width: 56px; height: 56px;
    border-radius: 50%;
    overflow: hidden;
    display: block;
    background: var(--sf-bg);
    box-shadow: 0 0 0 2px #fff, 0 2px 12px rgba(20,14,17,.34);
    transition: transform .14s ease, box-shadow .14s ease;
}
.vf-me:hover, .vf-me:focus-visible {
    transform: scale(1.06);
    box-shadow: 0 0 0 2px #fff, 0 4px 14px rgba(20,14,17,.44);
}
.vf-me img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vf-me-i {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--sf-disp); font-weight: 700; font-size: 22px;
    color: #fff;
    background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent));
}

/* Still smaller on a phone than on desktop, but no longer jammed into the
   corner — the inset grows proportionally so it clears the hero's rounded
   edge instead of sitting on it. */
@media (max-width: 768px) {
    .vf-me { width: 48px; height: 48px; top: 16px; right: 16px; }
    .vf-me-i { font-size: 19px; }
}
.sf-hero-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; margin-bottom: 14px; gap: 10px 14px; }

/* CD-70 — the one ValoraFi mark on her page. Was a low-contrast mono string;
   now a proper lockup: a small "Powered by" kicker over the ValoraFi wordmark
   in the logo's serif and gold, with the Colombia flag beside it. */
.sf-powered {
    display: inline-flex; flex-direction: column; gap: 3px; line-height: 1;
}
/* ── SIZED TO MATCH MY MALL, EXACTLY (CD-144 applied here too) ──
   The Mall's lockup was scaled up from 20px/8px because at that size it read as
   a footnote on a standalone page. The storefront is the SAME kind of page and
   never got the same treatment, so the two surfaces disagreed about how big
   ValoraFi is. These four numbers — 10px kicker / .2em / 30px wordmark / 9px gap
   / 24×16 flag — are Mall/Index.cshtml's .vm-* values, copied deliberately.
   Change them together or the surfaces drift again. */
.sf-powered-k {
    font-family: var(--sf-mono); font-size: 10px; letter-spacing: .2em;
    color: var(--sf-muted); text-transform: uppercase;
}

/* 🔴 SCOPED to .sf-powered on purpose. `.sf-brand` is declared TWICE in this
   file for two unrelated components: this ValoraFi lockup, and the professional's
   avatar+name header block further down (`.sf-brand { display:flex; gap:16px }`).
   That later rule wins the cascade, so an unscoped rule here never applied its
   gap anyway — and widening the selector would resize her header block instead. */
.sf-powered .sf-brand { display: inline-flex; align-items: center; gap: 9px; }

.sf-brand-name {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700; font-size: 30px; letter-spacing: .01em;
    color: #a07820; line-height: 1;
}
.sf-brand-flag { display: inline-flex; }
.sf-brand-flag svg {
    display: block; border-radius: 2px;
    width: 24px; height: 16px;
    box-shadow: 0 0 0 .5px rgba(0,0,0,.15);
}
.sf-hero-actions-mini { display: flex; gap: 7px; }
.sf-mini {
    font-family: var(--sf-mono); font-size: 9px; padding: 5px 8px;
    border: 1px solid var(--sf-line); border-radius: 8px;
    background: rgba(255,255,255,.6); color: var(--sf-deep); text-decoration: none;
}
/* Inside the capsule the pills carry no border of their own — the capsule is
   the border. */
.sf-hero-actions-mini .sf-mini {
    border: none;
    background: transparent;
    color: var(--sf-ink-2, #6b6058);
    font-size: 9px;
    padding: 5px 9px;
    cursor: pointer;
    transition: color .14s ease;
}
.sf-hero-actions-mini .sf-mini:hover { color: var(--sf-deep); }

.sf-mini { cursor: pointer; }
/* The form wrapper must not break the row the language pills sit in. */
.sf-mini-f { display: inline-flex; margin: 0; }

/* The profile button — the storefront's only "you are signed in" signal, and the
   opt-in way back to her account. It opens the activity panel in the drawer. */
.sf-mini--icon {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0; width: 26px; height: 26px;
    border-radius: 50% !important;
    background: var(--sf-deep) !important;
    color: #fff !important;
}
.sf-mini--icon:hover { filter: brightness(1.15); }

.sf-brand { display: flex; align-items: center; gap: 16px; }
/* Her face is the largest thing in the header for a reason: on a storefront with
   no brand behind it, the person IS the brand. Rounded square, not a circle —
   a circle crops the hair and shoulders off a normal phone headshot, and it
   fights the square rhythm of the service and product cards underneath. */
.sf-avatar {
    width: 96px; height: 96px; border-radius: 22px; flex: 0 0 auto; object-fit: cover;
    border: 2px solid #fff; box-shadow: 0 4px 16px rgba(0,0,0,.18);
}
/* No photo → her initial on her own gradient. Never a broken-image icon. */
.sf-avatar-fallback {
    background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent));
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-family: var(--sf-disp); font-size: 38px; font-weight: 700;
}
.sf-name { font-family: var(--sf-disp); font-weight: 700; font-size: 21px; line-height: 1.03; color: var(--sf-deep); margin: 0; }
.sf-sub { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .1em; color: var(--sf-accent); text-transform: uppercase; margin-top: 4px; }
.sf-meta { display: flex; gap: 11px; align-items: center; margin-top: 6px; font-size: 11px; color: var(--sf-muted); flex-wrap: wrap; }
.sf-meta .sf-star { color: var(--sf-accent); font-weight: 600; display: inline-flex; align-items: center; gap: 3px; }

/* ── SAVE TO MY MALL — a follow-style pill under the identity ── */
.sf-save-f { margin: 0; }
.sf-save {
    display: inline-flex; align-items: center; gap: 6px; margin-top: 11px;
    padding: 7px 13px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--sf-line); background: #fff; color: var(--sf-deep);
    font-family: var(--sf-mono); font-size: 11px; font-weight: 600; letter-spacing: .02em;
    transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.sf-save:hover { border-color: var(--sf-deep); }

/* SAVED — a quiet, confirmed chip, not a loud solid block. A soft theme-tinted
   fill with deep text and the filled bookmark reads as "done" without shouting,
   which is the more elegant, professional look and stays clearly distinct from
   the white "Save" affordance (outline icon → filled icon does the rest).
   color-mix keeps the tint correct across all ten themes; the plain hex lines
   above each color-mix are the fallback for browsers that lack it. */
.sf-save.on {
    background: #f7eef0;
    background: color-mix(in srgb, var(--sf-deep) 8%, #fff);
    color: var(--sf-deep);
    border-color: #e7d4d8;
    border-color: color-mix(in srgb, var(--sf-deep) 22%, transparent);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
    letter-spacing: .04em;
}
.sf-save.on:hover {
    background: color-mix(in srgb, var(--sf-deep) 12%, #fff);
    border-color: color-mix(in srgb, var(--sf-deep) 38%, transparent);
}
.sf-save-ic { flex: 0 0 auto; }
.sf-voice {
    padding: 13px 18px; font-family: var(--sf-disp); font-style: italic;
    font-size: 14px; color: var(--sf-deep); text-align: center; line-height: 1.4; margin: 0;
}

/* Language switcher — a stranger may land here in any of the four cultures,
   and she shares this link across borders. Four letters, no dropdown. */
/* ── THE HEADER CLUSTER ───────────────────────────────────────────────
   Four language pills, a profile button and a sign-out, sitting in a row and
   each drawn to a different rhythm — it read as a toolbar someone assembled by
   accident. They are now ONE object: a single hairline capsule, one internal
   divider between "what language am I reading" and "who am I", the same height
   throughout. On her storefront, ValoraFi's chrome should look considered or it
   should not be visible at all. */
.sf-hero-actions-mini {
    display: inline-flex;
    align-items: center;
    gap: 0;
    padding: 3px;
    border: 1px solid var(--sf-line);
    border-radius: 999px;
    background: rgba(255,255,255,.72);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.sf-langs { display: flex; gap: 2px; }
.sf-lang {
    font-family: var(--sf-mono); font-size: 9px; letter-spacing: .04em;
    padding: 5px 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: transparent;
    color: var(--sf-ink-2, #6b6058);
    text-decoration: none; text-transform: uppercase;
    transition: background .14s ease, color .14s ease;
}
.sf-lang:hover { background: var(--sf-soft, #faf7f3); color: var(--sf-deep); }
.sf-lang.on { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }

/* ── CD-119: language glyph + menu (replaces the four letter pills) ── */
.sf-lang-dd { position: relative; }
.sf-lang-dd > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 10px;
    border: 1px solid var(--sf-line); background: #fff; color: var(--sf-ink-2, #6b6058);
    transition: color .14s ease, border-color .14s ease, background .14s ease;
}
.sf-lang-dd > summary::-webkit-details-marker { display: none; }
.sf-lang-dd > summary:hover { color: var(--sf-deep); border-color: var(--sf-deep); }
.sf-lang-dd[open] > summary { color: var(--sf-deep); border-color: var(--sf-deep); background: var(--sf-soft, #faf7f3); }
.sf-lang-menu {
    position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
    min-width: 168px; padding: 6px; border-radius: 12px;
    background: #fff; border: 1px solid var(--sf-line);
    box-shadow: 0 12px 30px rgba(0,0,0,.16);
    display: flex; flex-direction: column; gap: 2px;
}
.sf-lang-item {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; border-radius: 8px; text-decoration: none;
    font-family: var(--sf-body, inherit); font-size: 13px; color: var(--sf-deep);
    transition: background .12s ease;
}
.sf-lang-item:hover { background: var(--sf-soft, #faf7f3); text-decoration: none; }
.sf-lang-item.on { font-weight: 600; }
.sf-lang-tick { width: 12px; color: var(--sf-accent); font-size: 12px; flex: none; }
.sf-lang-nm { flex: 1 1 auto; }
.sf-lang-cd { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em; color: var(--sf-muted); }

/* Language | identity. One hairline, so the two ideas do not run together. */
.sf-hero-actions-mini > .sf-mini,
.sf-hero-actions-mini > .sf-mini-f {
    margin-left: 6px;
    padding-left: 6px;
    border-left: 1px solid var(--sf-line);
    border-radius: 0;
}
.sf-hero-actions-mini > .sf-mini-f + .sf-mini,
.sf-hero-actions-mini > .sf-mini + .sf-mini-f {
    border-left: none;
    margin-left: 0;
    padding-left: 0;
}

/* Hero media on MOBILE — a slim scrolling strip, not a wall.
   Un-styled, these tiles rendered at natural image size and ate a third of
   the viewport before the customer saw a single price. The hero introduces
   her; the carta is what she came for. */
.sf-hero-r { display: flex; gap: 6px; overflow-x: auto; padding: 12px 18px 0; scrollbar-width: none; }
.sf-hero-r::-webkit-scrollbar { display: none; }
.sf-tile {
    flex: 0 0 auto; width: 68px; height: 84px; border-radius: 9px; overflow: hidden;
    position: relative; background: linear-gradient(160deg, var(--sf-deep), var(--sf-accent));
    display: flex; align-items: flex-end; padding: 5px;
}
.sf-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sf-tile .ml {
    position: relative; z-index: 2; font-family: var(--sf-mono); font-size: 7px;
    color: #fff; background: rgba(30,20,25,.6); padding: 2px 5px; border-radius: 7px;
}

/* ── STICKY SECTION NAV ─────────────────────────────────────── */
.sf-nav {
    position: sticky; top: 0; z-index: 15;
    display: flex; gap: 7px; padding: 11px 18px;
    background: color-mix(in srgb, var(--sf-bg) 95%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--sf-line);
    overflow-x: auto; scrollbar-width: none;
}
.sf-nav::-webkit-scrollbar { display: none; }
.sf-nav a {
    font-size: 12px; font-weight: 600; color: var(--sf-deep); text-decoration: none;
    padding: 6px 12px; border-radius: 18px; background: #fff;
    border: 1px solid var(--sf-line); white-space: nowrap;
}
.sf-nav a.on { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }
.sf-nav a .n { font-family: var(--sf-mono); font-size: 8px; opacity: .6; margin-left: 3px; }

/* ── SECTIONS ───────────────────────────────────────────────── */
.sf-sect { padding: 20px 18px 2px; scroll-margin-top: 60px; }
.sf-sect-hd { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; gap: 10px; }
.sf-sect-t { font-family: var(--sf-disp); font-weight: 700; font-size: 20px; color: var(--sf-deep); margin: 0; }
.sf-sect-c { font-family: var(--sf-mono); font-size: 10px; color: var(--sf-muted); }
.sf-group-t {
    font-family: var(--sf-mono); font-size: 11px; letter-spacing: .1em;
    color: var(--sf-accent); text-transform: uppercase;
    margin: 14px 0 10px; display: flex; align-items: center; gap: 8px;
}
.sf-group-t::after { content: ""; flex: 1; height: 1px; background: var(--sf-line); }
.sf-see-all {
    font-family: var(--sf-mono); font-size: 11px; font-weight: 500; color: var(--sf-deep);
    text-decoration: none; display: inline-flex; align-items: center; gap: 4px;
    background: #fff; border: 1px solid var(--sf-line); border-radius: 8px; padding: 6px 10px;
}

/* ── PLAN SELECTOR — the modifier engine, live ─────────────── */
.sf-plan-wrap { background: #fff; border: 1px solid var(--sf-line); border-radius: 14px; padding: 14px; margin-bottom: 12px; }
.sf-plan-title { font-family: var(--sf-disp); font-weight: 700; font-size: 18px; color: var(--sf-deep); line-height: 1.1; margin: 0; }
.sf-plan-sub { font-size: 11.5px; color: var(--sf-muted); margin: 3px 0 0; line-height: 1.45; }
.sf-kick {
    font-family: var(--sf-mono); font-size: 10px; letter-spacing: .1em;
    color: var(--sf-accent); text-transform: uppercase; margin: 12px 0 8px;
}
.sf-plan-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sf-plan {
    border: 1.5px solid var(--sf-line); border-radius: 12px; padding: 11px 10px;
    cursor: pointer; text-align: center; background: #fff; position: relative; transition: .12s;
}
.sf-plan .pn { font-family: var(--sf-disp); font-weight: 700; font-size: 14px; color: var(--sf-ink); }
.sf-plan .pp { font-family: var(--sf-mono); font-size: 13px; color: var(--sf-ink); margin-top: 4px; }
.sf-plan.sel { border-color: var(--sf-accent); background: var(--sf-soft); box-shadow: 0 3px 12px rgba(0,0,0,.08); }
.sf-plan .badge {
    position: absolute; top: -8px; left: 50%; transform: translateX(-50%);
    font-family: var(--sf-mono); font-size: 7.5px; letter-spacing: .05em;
    background: var(--sf-accent); color: #fff; padding: 2px 7px; border-radius: 8px; white-space: nowrap;
}
/* Inclusions swap when the plan changes — each plan sells a different promise. */
.sf-inc { list-style: none; margin: 12px 0 0; padding: 0; }
.sf-inc li { font-size: 12px; color: var(--sf-ink); line-height: 1.4; padding: 4px 0 4px 18px; position: relative; }
.sf-inc li::before { content: ""; position: absolute; left: 0; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--sf-deep); }

.sf-addon-row {
    display: flex; align-items: center; gap: 10px; border: 1px solid var(--sf-line);
    border-radius: 11px; padding: 10px 12px; margin-top: 8px; cursor: pointer; background: #fff;
}
.sf-addon-row.on { border-color: var(--sf-accent); background: var(--sf-soft); }
.sf-addon-check {
    width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--sf-accent);
    flex: 0 0 auto; display: flex; align-items: center; justify-content: center; color: transparent;
}
.sf-addon-row.on .sf-addon-check { background: var(--sf-accent); color: #fff; }
.sf-addon-n { font-size: 12.5px; font-weight: 500; flex: 1; }
.sf-addon-p { font-family: var(--sf-mono); font-size: 12px; color: var(--sf-deep); white-space: nowrap; }

.sf-loc { display: flex; gap: 8px; margin-top: 4px; }
.sf-lc {
    flex: 1; border: 1.5px solid var(--sf-line); border-radius: 11px; padding: 10px 12px;
    cursor: pointer; display: flex; align-items: center; gap: 9px; font-size: 12.5px; background: #fff;
}
.sf-lc.sel { border-color: var(--sf-accent); background: var(--sf-soft); }
.sf-lc .lcr { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--sf-accent); flex: 0 0 auto; }
.sf-lc.sel .lcr { box-shadow: inset 0 0 0 3px var(--sf-accent); }
.sf-lc .lcp { margin-left: auto; font-family: var(--sf-mono); font-size: 11px; color: var(--sf-deep); white-space: nowrap; }

.sf-booktotal {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--sf-line); flex-wrap: wrap;
}
.sf-booktotal .tt { font-size: 11px; color: var(--sf-muted); }
.sf-booktotal .tot { font-family: var(--sf-disp); font-weight: 700; font-size: 22px; color: var(--sf-deep); }
.sf-abn { font-family: var(--sf-mono); font-size: 12px; color: var(--sf-deep); background: var(--sf-soft); padding: 5px 10px; border-radius: 7px; }
.sf-btn-book {
    background: var(--sf-accent); color: #fff; border: none; border-radius: 9px;
    padding: 12px 18px; font-weight: 600; font-size: 13px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 7px; font-family: var(--sf-body);
}
.sf-btn-book:disabled { opacity: .55; cursor: not-allowed; }

/* ── PAYOUT DISCLOSURE — "ValoraFi never holds your money" ─── */
.sf-payout {
    display: flex; gap: 11px; align-items: flex-start;
    background: linear-gradient(135deg, var(--sf-soft), var(--sf-bg));
    border: 1px solid var(--sf-line); border-radius: 12px; padding: 12px 14px; margin-top: 10px;
}
.sf-payout svg { color: var(--sf-accent); flex: 0 0 auto; margin-top: 2px; }
.sf-payout .pt { font-size: 12.5px; color: var(--sf-ink); font-weight: 500; line-height: 1.4; }
.sf-payout .ps { font-family: var(--sf-mono); font-size: 10px; color: var(--sf-muted); margin-top: 4px; line-height: 1.5; }
.sf-indriver {
    display: inline-flex; align-items: center; gap: 6px; font-family: var(--sf-mono);
    font-size: 9px; letter-spacing: .06em; color: var(--sf-green);
    background: #e8f4ee; border: 1px solid #bfe3d1; padding: 3px 8px; border-radius: 20px; margin-top: 6px;
}
.sf-policy {
    background: #fff; border: 1px solid var(--sf-line); border-radius: 12px; padding: 12px 14px;
    display: flex; gap: 10px; font-size: 12px; color: var(--sf-muted); line-height: 1.5; margin-top: 12px;
}
.sf-policy svg { color: var(--sf-deep); flex: 0 0 auto; margin-top: 1px; }

/* ── SIMPLE SERVICE CARD (no plans) ─────────────────────────── */
/* GRID, not flex, so the proof row can break out of the text column and span the
   whole card. As a flex row, her photos and products started beside the 82px
   thumbnail — indented against every other block on the page. */
.sf-svc {
    background: #fff; border: 1px solid var(--sf-line); border-radius: 14px;
    padding: 13px; margin-bottom: 11px;
    display: grid; grid-template-columns: auto 1fr; gap: 12px;
    align-items: start;
}
/* Full bleed across both columns — flush with the card, like the plan services. */
.sf-svc-proof { grid-column: 1 / -1; }
.sf-svc-proof .sf-media-strip { margin-top: 4px; }
.sf-svc-media {
    width: 64px; height: 80px; border-radius: 10px; flex: 0 0 auto; position: relative;
    overflow: hidden; background: linear-gradient(160deg, var(--sf-deep), var(--sf-accent)); opacity: .9;
}
.sf-svc-media img { width: 100%; height: 100%; object-fit: cover; }
.sf-svc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sf-svc-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.sf-svc-name { font-family: var(--sf-disp); font-weight: 700; font-size: 15px; color: var(--sf-ink); line-height: 1.1; margin: 0; }
.sf-svc-price { font-family: var(--sf-mono); font-size: 14px; color: var(--sf-ink); white-space: nowrap; text-align: right; }
.sf-svc-inc {
    font-size: 11px; color: var(--sf-muted); line-height: 1.4; margin: 5px 0 8px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-svc-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: auto; }
.sf-tag {
    font-family: var(--sf-mono); font-size: 9.5px; color: var(--sf-deep);
    background: var(--sf-soft); padding: 4px 8px; border-radius: 6px;
}
.sf-tag-muted { color: var(--sf-muted); background: var(--sf-bg); border: 1px solid var(--sf-line); }
.sf-svc-foot .sf-btn-book { margin-left: auto; padding: 8px 14px; font-size: 12px; }

/* ══ HORIZONTAL RAILS ══════════════════════════════════════════
   Aura videos and products both scroll sideways. They ALREADY had overflow-x,
   so they were scrollable — but the last card stopped dead at the section's
   padding with nothing past it, which reads as "cut off" rather than "keep
   going". Two fixes, and they are the difference between a rail people swipe
   and a rail people think is broken:

     1. BLEED TO THE EDGE. The row is pulled out to the full screen width and
        given its own padding, so a card is always half-visible at the right
        margin. A sliced card is the only honest signal that there is more.
     2. SNAP + MOMENTUM. Cards settle on their left edge instead of stopping
        mid-card, and iOS gets its native flick.

   scroll-padding matches the bleed so a snapped card is never jammed against
   the screen edge. */
.sf-rail {
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;               /* a swipe does not navigate back */
    scroll-padding-left: 18px;
}
.sf-rail > * { scroll-snap-align: start; }

@media (max-width: 899px) {
    .sf-rail {
        margin-left: -18px; margin-right: -18px;  /* out to the screen edge … */
        padding-left: 18px; padding-right: 18px;  /* … without losing the gutter */
    }
}

/* ── AURA VIDEOS ────────────────────────────────────────────── */
.sf-vrow { display: flex; gap: 11px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
.sf-vrow::-webkit-scrollbar { display: none; }
.sf-vcard {
    flex: 0 0 122px; border-radius: 13px; overflow: hidden; position: relative;
    aspect-ratio: 9/14; display: flex; align-items: flex-end; padding: 10px;
    background: linear-gradient(160deg, var(--sf-deep), var(--sf-accent));
    text-decoration: none;
}
.sf-vcard img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sf-vcard .vshade { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,.55), transparent 55%); }
.sf-vcard .vplay { position: absolute; top: 10px; right: 10px; color: #fff; z-index: 2; }
.sf-vcard .vpills { position: absolute; top: 10px; left: 10px; display: flex; gap: 4px; z-index: 2; }
.sf-vpill { font-family: var(--sf-mono); font-size: 8px; font-weight: 600; padding: 3px 6px; border-radius: 9px; color: #fff; }
.sf-vpill.b { background: var(--sf-deep); }
.sf-vpill.s { background: var(--sf-accent); }
.sf-vcard .vt {
    font-family: var(--sf-disp); font-weight: 700; font-size: 12px; color: #fff;
    line-height: 1.15; text-shadow: 0 1px 6px rgba(0,0,0,.5); position: relative; z-index: 2;
}

/* ── SERVICE MEDIA STRIP ────────────────────────────────────── */
/* Her work, under the service it belongs to. Before/After first — it is
   what actually sells a beauty service. Scrolls sideways; a media strip
   that wraps steals the vertical room the carta needs. */
/* Momentum, but NO edge-bleed: this strip lives INSIDE a service card, and
   pulling it to the screen edge would tear it out of the card it belongs to. */
.sf-media-strip {
    display: flex; gap: 8px; overflow-x: auto; margin-top: 12px; padding-bottom: 4px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
}
.sf-media-strip::-webkit-scrollbar { display: none; }
.sf-media-tile {
    flex: 0 0 auto; width: 72px; height: 90px; border-radius: 9px; overflow: hidden;
    position: relative; background: linear-gradient(160deg, var(--sf-deep), var(--sf-accent));
    display: flex; align-items: flex-end; padding: 5px;
}
.sf-media-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sf-media-tile .ml {
    position: relative; font-family: var(--sf-mono); font-size: 7px; color: #fff;
    background: rgba(30,20,25,.6); padding: 2px 5px; border-radius: 7px; z-index: 2;
}
/* A/D pair renders as one split tile — the before and the after are one claim. */
.sf-media-tile.ba::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
    width: 1.5px; background: rgba(255,255,255,.85); z-index: 1;
}
.sf-media-tile.video .vp {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 1.1rem; z-index: 2; text-shadow: 0 1px 6px rgba(0,0,0,.5);
}

/* WEB-MOBILE media pager — left/right chevrons over the photo/video strip.
   Hidden on desktop (drag/scroll is fine there); hidden by JS at each end or
   when the whole strip already fits. Accent disc to match the up/down proof
   chevron so the storefront reads as one control language. */
.sf-media-scroll { position: relative; }
.sf-media-arrow {
    display: none;
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 28px; height: 28px; border-radius: 50%; z-index: 3; padding: 0;
    align-items: center; justify-content: center;
    background: var(--sf-accent); color: #fff; border: none; cursor: pointer;
    box-shadow: 0 1px 5px rgba(0,0,0,.28);
}
.sf-media-arrow.prev { left: 3px; }
.sf-media-arrow.next { right: 3px; }
@media (max-width: 991.98px) {
    .sf-media-arrow { display: inline-flex; }
    .sf-media-arrow[hidden] { display: none; }
}

/* Products attached to a service — the post-service popup, previewed. */
.sf-svc-prods { display: flex; gap: 6px; margin-top: 10px; align-items: center; flex-wrap: wrap; }
.sf-svc-prod-chip {
    display: inline-flex; align-items: center; gap: 5px;
    border: 1px solid var(--sf-line); border-radius: 20px; padding: 3px 9px 3px 3px;
    background: #fff; font-size: 10.5px; color: var(--sf-ink); text-decoration: none;
}
.sf-svc-prod-chip img { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }
.sf-svc-prod-chip .ph { width: 20px; height: 20px; border-radius: 50%; background: var(--sf-soft); }

/* ── PRODUCTS ───────────────────────────────────────────────── */
.sf-prow { display: flex; gap: 11px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
.sf-prow::-webkit-scrollbar { display: none; }
.sf-prod {
    flex: 0 0 194px; background: #fff; border: 1px solid var(--sf-line);
    border-radius: 12px; overflow: hidden; display: flex; flex-direction: column;
}
.sf-prod.oos { opacity: .72; }

/* IMAGE FIT — square well, product CONTAINED, never cropped.
   Was: a 118px band with object-fit:cover, which guillotined the top and bottom
   off every portrait bottle and left landscape ones floating in dead space. A
   product shot is the thing being sold; cropping it is not a style choice.
   contain + a square well + padding = every SKU sits the same, whatever its
   source aspect ratio, and nothing is amputated. */
/* The well is generous and the product fills it. `contain` guarantees nothing
   is cropped; the padding is small on purpose so "not cropped" doesn't turn
   into "postage stamp floating in white". */
.sf-prod-img {
    aspect-ratio: 1 / 1; background: #fff; display: flex;
    align-items: center; justify-content: center; position: relative;
    /* Was 5px. On a white well the product no longer has a visible white photo-
       box to fill the frame, so it read small — a tighter pad lets it fill more
       of the well without cropping (contain still guarantees nothing is
       amputated). Applies to both her shelf and the catalogue, so they match. */
    padding: 2px; border-bottom: 1px solid var(--sf-line);
}
.sf-prod-img img { width: 100%; height: 100%; object-fit: contain; }
/* 🔴 EVERY ROW HAS A FIXED HEIGHT, so the price lands on the same line on every
   card in the rail. Products have brands or not, reviews or not, one-line names
   or three — left to itself the block collapsed to fit and the prices staggered
   like a broken picket fence. The rows are always in the DOM (see the view) and
   they always occupy the same space, empty or not. */
.sf-prod-b { padding: 9px 10px; display: flex; flex-direction: column; flex: 1; }
/* 🔴 THE WHOLE TEXT GROUP IS ANCHORED TO THE BOTTOM — brand, name, price, as one
   block. The `auto` lives HERE, on the first row, so all three travel down
   together and any slack falls ABOVE the brand instead of opening a hole in the
   middle of the card. Every row below has a fixed height, so brand, name and
   price each land on exactly the same line on every card in the rail. */
.sf-prod-brand {
    font-family: var(--sf-mono); font-size: 8px; letter-spacing: .06em;
    color: var(--sf-muted); text-transform: uppercase;
    height: 11px; line-height: 11px;              /* reserved even when there is no brand */
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    margin-top: auto;                              /* ← the group falls to the bottom */
}
/* Exactly two lines. A long name is clipped with an ellipsis rather than being
   allowed to push this card taller than the one beside it. */
.sf-prod-n {
    font-size: 12.5px; font-weight: 500; line-height: 1.3; margin-top: 2px;
    height: 32.5px;                                /* 2 × 1.3 × 12.5px */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.sf-prod-rating {
    display: flex; align-items: center; gap: 2px; color: var(--sf-accent);
    font-size: 9px; margin-top: 4px;
    height: 12px;                                  /* reserved even with no reviews */
}
.sf-prod-rating .rc { font-family: var(--sf-mono); color: var(--sf-muted); margin-left: 3px; }
/* The last row of the group — no `auto` here now, or it would fight the brand's
   and re-open the gap it just closed. Two autos in one column and the first wins. */
.sf-prod-p { font-family: var(--sf-mono); font-size: 13px; color: var(--sf-ink); padding-top: 6px; }
/* PINNED TO THE BOTTOM OF THE CARD. margin-top:auto inside the flex column,
   and .sf-prow stretches every card to the tallest one — so the button row
   sits on the same baseline across the whole rail instead of floating up
   under whichever product happened to have a one-line name. */
/* No margin-top:auto here — the PRICE claims the slack now. Two `auto`s in one
   column and the first one wins, which is what pushed the price around. */
.sf-prod-actions { display: flex; align-items: stretch; gap: 6px; padding-top: 10px; }
/* ── IN STOCK READS AS BUYABLE ────────────────────────────────────────
   "Ver detalles" now wears the SAME dark as the booking CTA (--sf-deep,
   white text). It was white-on-white outline, which made an in-stock product
   look no more available than an AGOTADO one — the two states were competing
   at the same visual weight, and the one you can actually buy was losing.

   The out-of-stock card mutes it back down (.sf-prod.oos below). The contrast
   IS the message: dark = you can have this; pale = you cannot.               */
.sf-prod-btn {
    flex: 1; border-radius: 8px; padding: 7px 6px; font-size: 10.5px; font-weight: 600;
    text-align: center; text-decoration: none; cursor: pointer;
    background: var(--sf-deep); color: #fff; border: 1px solid var(--sf-deep);
    font-family: var(--sf-body);
    display: inline-flex; align-items: center; justify-content: center; gap: 4px;
    transition: filter .15s ease, transform .12s ease;
}
.sf-prod-btn:hover { color: #fff; filter: brightness(1.15); transform: translateY(-1px); }

/* "VIEW DETAILS" broke across two lines on narrow phones and not on wide ones,
   so the card grew a row on some devices and not others and the rail lost its
   baseline. The label is one word now ("Detalles" / "Details"), and this is the
   belt: a button label on a card must never wrap, in any language. */
.sf-prod-btn { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* WHERE the service happens, when there is no choice to make. Never silence —
   a customer who is not told will guess, and half of them will guess wrong. */
.sf-bk-loc-fixed {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid var(--sf-line);
    background: var(--sf-soft, #faf7f3);
    font-size: 12.5px;
    color: var(--sf-ink);
}
.sf-bk-loc-fixed i { color: var(--sf-accent); font-size: 14px; }

/* OUT OF STOCK — the details button steps back to an outline. You can still
   read about it; you just can't buy it, and the card should say so before you
   read a word. */
.sf-prod.oos .sf-prod-btn {
    background: #fff;
    color: var(--sf-ink-3, #9a8f83);
    border-color: var(--sf-line);
}
.sf-prod.oos .sf-prod-btn:hover { filter: none; transform: none; color: var(--sf-deep); }

/* QUICK-ADD = a PLUS, not a gold slab.
   Soft accent-tinted square, accent glyph, subtle lift. Reads as an affordance
   rather than a billboard, and it survives all 10 palettes because it borrows
   the theme's accent instead of hardcoding ValoraFi gold. */
/* The + is now a SOLID accent slab, not a 12%-tint whisper. It is the button
   that actually takes her money; it should not be the palest thing on the card.
   Still the theme's accent rather than hardcoded gold, so all 10 palettes hold. */
.sf-prod-add {
    flex: 0 0 38px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 10px; text-decoration: none; cursor: pointer;
    background: var(--sf-accent);
    color: #fff;
    border: 1px solid color-mix(in srgb, var(--sf-accent) 80%, #000);
    box-shadow: 0 1px 3px rgba(0,0,0,.12);
    line-height: 1;
    transition: filter .15s ease, transform .12s ease, box-shadow .15s ease;
}
/* A REAL "+", drawn as a character, not an icon-font glyph. If bootstrap-icons
   fails to load — a bride on bad mobile data, exactly our reader — an <i class="bi">
   renders as an empty box and the buy button becomes invisible. A literal + always
   paints, and it says what the button does without a label. */
.sf-prod-add .pl { font-size: 21px; font-weight: 600; line-height: 1; margin-top: -2px; }
.sf-prod-add:hover {
    filter: brightness(1.12);
    box-shadow: 0 2px 6px rgba(0,0,0,.16);
    transform: translateY(-1px);
    color: #fff;
}
.sf-prod-add:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0,0,0,.08); }

/* OUT OF STOCK — bottom-right, in the buy control's slot, right of Details.
   Stated once, where it actually changes what you can do. Never on the image,
   and never as a count. */
.sf-prod-oos {
    flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    padding: 0 9px; border-radius: 10px;
    font-family: var(--sf-mono); font-size: 8.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
    background: #f4f1f1; color: #a03030; border: 1px solid #e6dcdc;
    cursor: not-allowed;
}
.sf-catalog-card {
    flex: 0 0 112px; border: 1.5px dashed var(--sf-accent); border-radius: 12px;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px; color: var(--sf-deep); background: var(--sf-soft);
    text-decoration: none; padding: 12px 8px; text-align: center;
}
.sf-catalog-card .cc-t { font-family: var(--sf-disp); font-weight: 700; font-size: 12px; line-height: 1.15; }
.sf-catalog-card .cc-s { font-family: var(--sf-mono); font-size: 8px; color: var(--sf-muted); }

/* Attribution strip — "you're shopping with her" */
.sf-attr {
    margin-top: 14px; display: flex; align-items: center; gap: 10px;
    padding: 11px 13px; border-radius: 11px;
    background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent)); color: #fff;
}
.sf-attr .at-t { font-weight: 600; font-size: 12px; }
.sf-attr .at-s { font-family: var(--sf-mono); font-size: 9px; opacity: .85; }

/* ── REVIEWS ────────────────────────────────────────────────── */
.sf-rsum { display: flex; align-items: center; gap: 16px; background: #fff; border: 1px solid var(--sf-line); border-radius: 12px; padding: 14px 18px; margin-bottom: 12px; }
.sf-rbig { font-family: var(--sf-disp); font-weight: 700; font-size: 36px; color: var(--sf-accent); line-height: 1; }
.sf-rstars { color: var(--sf-accent); font-size: 15px; letter-spacing: 2px; }
.sf-rsub { font-family: var(--sf-mono); font-size: 10px; color: var(--sf-muted); letter-spacing: 0; margin-top: 4px; }
.sf-rev { background: #fff; border: 1px solid var(--sf-line); border-radius: 12px; padding: 13px; margin-bottom: 10px; }
.sf-rev-h { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; }
.sf-rav {
    width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto;
    object-fit: cover; background: var(--sf-deep);
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 11px; font-weight: 600;
}
.sf-rev-name { font-size: 12px; font-weight: 600; }
.sf-rev-st { color: var(--sf-accent); font-size: 11px; letter-spacing: 1px; }
.sf-rev-t { font-size: 12.5px; color: var(--sf-ink); line-height: 1.5; margin: 0; }

/* ── SHARE + FOOTER ─────────────────────────────────────────── */
.sf-share {
    margin: 18px 18px; border-radius: 14px; padding: 15px; color: #fff;
    background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent));
}
.sf-share-k { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .13em; opacity: .85; text-transform: uppercase; margin-bottom: 9px; }
/* CD-69 — the copy field and share button were captions. The link is a
   primary affordance (it is the whole point of the page), so the box is
   taller, the URL reads bigger, and both buttons are real touch targets. */
.sf-link { display: flex; align-items: center; gap: 10px; background: rgba(255,255,255,.16); border-radius: 12px; padding: 12px 14px; }
.sf-link .u { font-family: var(--sf-mono); font-size: 13.5px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Store-link reveal — the URL sits collapsed behind its own icon. The toggle is
   a bare icon-button that inherits the surrounding colour/size (so it changes
   nothing about the box or the Copy/share buttons); tapping it reveals the URL,
   tapping again hides it. */
.sf-url-tog {
    display: inline-flex; align-items: center; justify-content: center;
    background: none; border: none; padding: 0; margin: 0;
    color: inherit; font: inherit; line-height: 1; cursor: pointer;
    transition: opacity .14s ease;
}
.sf-url-tog:hover { opacity: .68; }
.sf-url-tog[aria-expanded="true"] { opacity: .68; }
.sf-url-val[hidden] { display: none; }
.sf-link .cp { background: #fff; color: var(--sf-deep); border: none; border-radius: 9px; padding: 9px 14px; font-family: var(--sf-mono); font-size: 12px; font-weight: 600; cursor: pointer; min-height: 40px; }
.sf-foot { padding: 4px 18px 24px; text-align: center; margin-top: auto; }
.sf-foot .pv { font-family: var(--sf-mono); font-size: 9.5px; letter-spacing: .08em; color: var(--sf-muted); text-transform: uppercase; }
.sf-foot .langs { font-family: var(--sf-mono); font-size: 8.5px; color: var(--sf-muted); opacity: .65; margin-top: 7px; }

.sf-empty {
    text-align: center; padding: 40px 20px; color: var(--sf-muted);
    background: #fff; border: 1px dashed var(--sf-line); border-radius: 16px; margin: 0 18px;
}

/* ══════════════════════════════════════════════════════════════
   DESKTOP — the editorial layout. Mobile is the baseline above.
   ══════════════════════════════════════════════════════════════ */
@media (min-width: 900px) {
    /* The hero introduces her; it does not ARRIVE as the page. Capped so the
       carta is visible above the fold — the media grid was eating ~30% of the
       viewport, which pushed the thing she is actually selling below it. */
    /* CD-124 — the 300px cap used to sit on the whole hero with overflow:hidden,
       which clipped the identity kicker ("… STORE") whenever the left column ran
       tall (now taller still with the app-shell icons). Cap the MEDIA column only
       (below) and let the identity column define its own height, so text is never
       cut. align-items:start stops the short column from stretching. */
    .sf-hero { display: grid; grid-template-columns: 1.25fr 1fr; padding: 0; align-items: start; }
    .sf-hero-l { padding: 26px 40px; }
    .sf-hero-top { margin-bottom: 16px; }
    /* No mobile downscale for the lockup — the Mall carries 30px/24×16 at every
       width, and "same size as the Mall" has to hold on a phone too, which is
       where nearly all of this traffic actually is. ~150px wide at 390px
       viewport, so it still fits beside the rail. */
    .sf-avatar { width: 124px; height: 124px; border-radius: 26px; }
    .sf-avatar-fallback { font-size: 48px; }
    .sf-name { font-size: 31px; }
    .sf-sub { font-size: 10px; }
    .sf-meta { font-size: 12.5px; gap: 14px; margin-top: 9px; }
    .sf-voice { text-align: left; font-size: 17px; padding: 16px 40px 0; max-width: 460px; margin: 0; }

    /* Media tile grid: one tall + two square, the mockup's hero-r —
       but bounded by the hero's max-height so it can't dominate. */
    .sf-hero-r {
        display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
        gap: 3px; padding: 3px; overflow: hidden;
        align-self: start; max-height: 300px;   /* CD-124 — the cap lives here now */
    }
    .sf-tile {
        flex: none; width: auto; height: auto; aspect-ratio: 1;
        border-radius: 0; padding: 8px;
    }
    .sf-tile:first-child { grid-row: span 2; aspect-ratio: auto; }
    .sf-tile .ml { font-size: 8px; padding: 2px 6px; }

    .sf-nav { padding: 13px 40px; gap: 10px; }
    .sf-nav a { font-size: 13px; padding: 7px 15px; background: transparent; border-color: transparent; }
    .sf-nav a.on { background: var(--sf-deep); }
    .sf-nav .sf-share-inline { margin-left: auto; display: flex; align-items: center; gap: 10px; font-family: var(--sf-mono); font-size: 13.5px; color: var(--sf-deep); background: #fff; border: 1px solid var(--sf-line); border-radius: 11px; padding: 11px 16px; }
    .sf-nav .sf-share-inline .cp { background: var(--sf-deep); color: #fff; border: none; border-radius: 8px; padding: 8px 13px; font-family: var(--sf-mono); font-size: 12px; font-weight: 600; cursor: pointer; min-height: 38px; }

    .sf-main { padding: 30px 40px 40px; max-width: 1000px; margin: 0 auto; }
    .sf-sect { padding: 0; margin-bottom: 34px; }
    .sf-sect-t { font-size: 26px; }
    .sf-plan-wrap { padding: 18px; }
    .sf-plan-title { font-size: 20px; }
    .sf-plan-grid { grid-template-columns: repeat(4, 1fr); gap: 9px; }
    .sf-loc { max-width: 480px; }

    /* Two-up service cards; video + product rails become grids. */
    .sf-svc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
    .sf-svc { margin-bottom: 0; padding: 15px; }
    .sf-svc-media { width: 82px; height: 100px; }
    .sf-svc-name { font-size: 16px; }
    .sf-svc-price { font-size: 15px; }

    .sf-vrow { display: grid; grid-template-columns: repeat(5, 1fr); overflow: visible; gap: 12px; }
    .sf-vcard { flex: none; }
    .sf-prow { display: grid; grid-template-columns: repeat(4, 1fr); overflow: visible; gap: 12px; }
    .sf-prod, .sf-catalog-card { flex: none; }
    .sf-prod-img { height: 150px; }
    .sf-media-tile { width: 84px; height: 104px; }

    .sf-rev-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
    .sf-rev { margin-bottom: 0; }
    .sf-rbig { font-size: 40px; }

    .sf-share { display: none; }  /* the nav carries the share link on desktop */
    .sf-foot {
        padding: 22px 40px; text-align: left;
        background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent));
        display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;
    }
    .sf-foot .pv, .sf-foot .langs { color: #fff; opacity: .9; margin: 0; }
    .sf-empty { margin: 0; }
}

/* The inline share pill is desktop-only; the card is mobile-only. */
.sf-nav .sf-share-inline { display: none; }
@media (min-width: 900px) { .sf-nav .sf-share-inline { display: flex; } }

/* ══════════════════════════════════════════════════════════════
   PRODUCT DETAIL — /store/{handle}/producto/{id}
   Her palette, her page. Every token below is the theme's, so this
   view recolours with the storefront and never shows ValoraFi gold.
   ══════════════════════════════════════════════════════════════ */
.sf-pd { max-width: 1080px; margin: 0 auto; padding: 18px 16px 40px; }

.sf-pd-back {
    display: inline-flex; align-items: center; gap: 8px;
    text-decoration: none; color: var(--sf-deep); font-weight: 600; font-size: 13px;
    padding: 8px 12px; border-radius: 10px; border: 1px solid var(--sf-line);
    background: #fff; margin-bottom: 18px;
}
.sf-pd-back:hover { background: var(--sf-soft); color: var(--sf-deep); }

.sf-pd-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 28px; align-items: start; }

/* Gallery — contained, never cropped. A product shot is the thing being sold. */
.sf-pd-main {
    aspect-ratio: 1 / 1; background: #fff; border: 1px solid var(--sf-line);
    border-radius: 14px; display: flex; align-items: center; justify-content: center;
    padding: 18px; overflow: hidden;
}
.sf-pd-main img { width: 100%; height: 100%; object-fit: contain; }

.sf-pd-thumbs { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.sf-pd-th {
    width: 62px; height: 62px; padding: 5px; border-radius: 10px; cursor: pointer;
    background: #fff; border: 1px solid var(--sf-line);
    display: flex; align-items: center; justify-content: center;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.sf-pd-th img { width: 100%; height: 100%; object-fit: contain; }
.sf-pd-th.on { border-color: var(--sf-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--sf-accent) 22%, transparent); }

.sf-pd-brand { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-muted); }
.sf-pd-n { font-family: var(--sf-disp); font-size: 27px; line-height: 1.18; margin: 6px 0 0; color: var(--sf-ink); }
.sf-pd-rating { display: flex; align-items: center; gap: 3px; color: var(--sf-accent); font-size: 12px; margin-top: 8px; }
.sf-pd-rating .rc { font-family: var(--sf-mono); color: var(--sf-muted); font-size: 10px; margin-left: 5px; }
.sf-pd-p { font-family: var(--sf-mono); font-size: 24px; color: var(--sf-ink); margin-top: 14px; }
.sf-pd-d { font-size: 14px; line-height: 1.6; color: var(--sf-body-ink, var(--sf-ink)); margin-top: 12px; opacity: .85; }

.sf-pd-actions { margin-top: 20px; }

/* Add-to-cart: the same PLUS affordance as the rail, at full width. Not a
   gold slab — it borrows the theme accent, so it works on all 10 palettes. */
.sf-pd-add {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; padding: 13px 16px; border-radius: 12px; cursor: pointer;
    text-decoration: none; font-weight: 600; font-size: 14px;
    background: var(--sf-accent); color: #fff; border: 1px solid var(--sf-accent);
    box-shadow: 0 2px 8px rgba(0,0,0,.10);
    transition: transform .12s ease, box-shadow .15s ease, filter .15s ease;
}
.sf-pd-add .pl { font-size: 19px; font-weight: 600; line-height: 1; margin-top: -2px; }
.sf-pd-add:hover { color: #fff; filter: brightness(1.06); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,.14); }
.sf-pd-add:active { transform: translateY(0); }

/* Out of stock — stated once, in the buy control's place. Never a count. */
.sf-pd-oos {
    display: inline-flex; align-items: center; justify-content: center;
    width: 100%; padding: 13px 16px; border-radius: 12px;
    font-family: var(--sf-mono); font-size: 11px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    background: #f4f1f1; color: #a03030; border: 1px solid #e6dcdc; cursor: not-allowed;
}

/* Ingredients — the secondary read, under the buy control. Deliberately the
   quiet twin of .sf-pd-add: same geometry and radius so the pair reads as one
   stack, but outlined in the theme accent instead of filled by it, because
   nothing here should compete with the thing that takes her money. Borrows
   --sf-accent, so it lands correctly on all 10 palettes. */
.sf-pd-ing {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; padding: 12px 16px; margin-top: 10px; border-radius: 12px;
    cursor: pointer; font-weight: 600; font-size: 13.5px;
    background: transparent; color: var(--sf-accent);
    border: 1px solid var(--sf-accent);
    transition: background .15s ease, color .15s ease, transform .12s ease;
}
.sf-pd-ing i { font-size: 15px; line-height: 1; }
.sf-pd-ing:hover { background: var(--sf-accent); color: #fff; transform: translateY(-1px); }
.sf-pd-ing:active { transform: translateY(0); }
.sf-pd-ing:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 2px; }

.sf-pd-attr { margin-top: 18px; }

@media (max-width: 780px) {
    .sf-pd-grid { grid-template-columns: 1fr; gap: 20px; }
    .sf-pd-n { font-size: 22px; }
    .sf-pd-p { font-size: 21px; }
}

/* The rest of her shelf, ON THE DETAIL PAGE — bigger cards than the storefront
   rail (3-up instead of 4, taller image). Scoped to .sf-pd so the storefront
   rail is untouched. */
@media (min-width: 900px) {
    .sf-pd .sf-prow { grid-template-columns: repeat(3, 1fr); }
    .sf-pd .sf-prod-img { height: 200px; }
}

/* ══════════════════════════════════════════════════════════════
   PROOF COLLAPSE — the service card is a FIXED SHAPE
   Media + linked products fold behind one control, so a service with
   six photos is not three times the height of one with none. Collapsed
   is not hidden: the toggle names what is inside, so she gets credit
   for the work whether or not the customer opens it.
   ══════════════════════════════════════════════════════════════ */
.sf-proof { margin-top: 12px; border-top: 1px solid var(--sf-line); padding-top: 10px; }
.sf-proof-tog {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 9px 11px; border-radius: 10px; cursor: pointer;
    background: var(--sf-soft); border: 1px solid var(--sf-line);
    color: var(--sf-deep); font-family: var(--sf-body); font-size: 12px; font-weight: 600;
}
.sf-proof-tog:hover { filter: brightness(.98); border-color: var(--sf-accent); }
.sf-proof-tog .pt-l { display: inline-flex; align-items: center; gap: 8px; }

/* THE CHEVRON HAS TO LOOK LIKE A DOOR.
   It was an 11px glyph in body-text grey, which reads as punctuation, not as a
   control — so nobody knew the panel opened, and her photos, her before/afters,
   her videos and her products sat behind a button no one pressed. Those are her
   PROOF; a customer who never sees them never books.

   A filled accent disc, large enough to be a target on a thumb. It cannot be
   mistaken for decoration. */
.sf-proof-tog .pt-c {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px;
    border-radius: 50%;
    background: var(--sf-accent);
    color: #fff;
    font-size: 12px;
    transition: transform .2s ease, filter .14s ease;
}
.sf-proof-tog:hover .pt-c { filter: brightness(1.1); }
.sf-proof-tog.on .pt-c { transform: rotate(180deg); }

/* NO JUMP. Expanding reveals content BELOW the button, so the button itself must
   not move — otherwise the thing she just tapped slides out from under her thumb
   and she loses her place. */
.sf-proof { scroll-margin-top: 80px; }
.sf-proof-body { overflow-anchor: none; }
.sf-proof-body { padding-top: 10px; }

/* Media tiles are <button> now (they open the lightbox) — strip the UA chrome. */
.sf-media-tile { padding: 0; border: none; cursor: pointer; font: inherit; }
/* The compact card's strip — smaller tiles, same behaviour. Was an inline
   style="width:54px" on a dead <div>; it is a real button now. */
.sf-media-tile.sm { width: 54px; height: 66px; }
/* The Aura card is a <button> now (it plays in the viewer) — strip UA chrome. */
button.sf-vcard { padding: 0; border: none; cursor: pointer; font: inherit; text-align: left; }

/* ══ MEDIA VIEWER ══════════════════════════════════════════════
   A PANEL, not a bare image on a scrim. Her palette, a titled header, a
   close button — opening her work should look like part of her storefront,
   not like a browser artifact. Three shapes inside: photo · before/after
   pair · playable video. */
.sf-vw {
    position: fixed; inset: 0; z-index: 90;
    background: rgba(20,14,17,.72); backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center; padding: 20px;
    animation: sfVwIn .16s ease-out;
}
@keyframes sfVwIn { from { opacity: 0; } to { opacity: 1; } }

.sf-vw-panel {
    background: var(--sf-bg); border-radius: 16px; overflow: hidden;
    width: min(920px, 100%); max-height: 90vh;
    display: flex; flex-direction: column;
    box-shadow: 0 24px 64px rgba(0,0,0,.42);
    animation: sfVwPop .2s cubic-bezier(.2,.8,.3,1);
}
@keyframes sfVwPop { from { transform: scale(.97) translateY(6px); opacity: .5; } to { transform: none; opacity: 1; } }

.sf-vw-hd {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 13px 16px; border-bottom: 1px solid var(--sf-line);
    background: var(--sf-soft); flex: 0 0 auto;
}
.sf-vw-t { font-family: var(--sf-disp); font-weight: 700; font-size: 15px; color: var(--sf-deep); line-height: 1.2; }
.sf-vw-s { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-muted); margin-top: 3px; }
.sf-vw-x {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    background: #fff; color: var(--sf-deep); border: 1px solid var(--sf-line);
}
.sf-vw-x:hover { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }

.sf-vw-body { padding: 16px; overflow-y: auto; background: var(--sf-bg); }

/* One photo — contained, never cropped. */
.sf-vw-one { display: flex; justify-content: center; }
.sf-vw-one img { max-width: 100%; max-height: 68vh; object-fit: contain; border-radius: 10px; }

/* BEFORE + AFTER, TOGETHER. Side by side is the whole argument — a pair
   shown one at a time is two photos, not a transformation. */
.sf-vw-ba { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.sf-vw-ba figure { margin: 0; display: flex; flex-direction: column; gap: 7px; }
.sf-vw-ba img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
    border-radius: 10px; background: var(--sf-soft);
}
.sf-vw-ba figcaption {
    font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--sf-deep); text-align: center;
}

/* A real player. preload="none" in the markup — a bride on mobile data pays
   for the bytes only when she presses play. */
.sf-vw-video { display: flex; justify-content: center; }
.sf-vw-video video {
    width: 100%; max-height: 68vh; border-radius: 10px;
    background: #000; outline: none;
}

@media (max-width: 640px) {
    /* 🔴 FULLSCREEN ON MOBILE. The panel used to float with margins and a 90vh
       cap, so the video read small and — far worse — the product SHOP sheet
       (72% of an already-small video) collapsed to a crunched sliver. On a
       phone the viewer now takes the WHOLE screen; the media fills it and the
       shop sheet rises nearly full-height with a clean two-column grid. */
    .sf-vw { padding: 0; }
    .sf-vw-panel {
        width: 100%; max-width: 100%;
        height: 100vh; height: 100dvh;          /* dvh: account for mobile browser chrome */
        max-height: 100vh; max-height: 100dvh;
        border-radius: 0;
    }
    .sf-vw-body {
        flex: 1 1 auto; min-height: 0;
        padding: 10px;
        display: flex; flex-direction: column;
    }

    .sf-vw-ba { grid-template-columns: 1fr; }   /* stack, never squeeze to nothing */

    /* The active shape fills the tall body so nothing reads as cramped. */
    .sf-vw-one { flex: 1 1 auto; min-height: 0; align-items: center; }
    .sf-vw-one img { max-height: 100%; }
    .sf-vw-video { flex: 1 1 auto; min-height: 0; align-items: center; }
    .sf-vw-video video { width: 100%; height: 100%; max-height: none; object-fit: contain; }

    /* THE PRODUCT SHOP SHEET is sized in a media query placed AFTER its base
       rules (search "SHOP SHEET, MOBILE"). It must live there, not here: these
       overrides are earlier in the file than the base .sf-vshop rule, and with
       equal specificity the later base rule would win — which is exactly why the
       sheet kept rendering at 72%. */
}

/* ══ CHECKOUT DRAWER ═══════════════════════════════════════════
   AMANGO's structure — right-docked rail, ~420px desktop / full width on
   mobile, sticky header + sticky footer CTA, storefront DIMMED behind and
   NOT reflowed. Nazca's line-item cards inside. Her palette throughout. */
.sf-dw {
    position: fixed; inset: 0; z-index: 100;
    background: rgba(20,14,17,.5); backdrop-filter: blur(2px);
    display: flex; justify-content: flex-end;
    animation: sfVwIn .16s ease-out;
}
.sf-dw-panel {
    width: min(420px, 100%); height: 100%;
    background: var(--sf-bg);
    display: flex; flex-direction: column;      /* header · scroll · footer */
    box-shadow: -12px 0 40px rgba(0,0,0,.28);
    animation: sfDwIn .22s cubic-bezier(.2,.8,.3,1);
}
@keyframes sfDwIn { from { transform: translateX(24px); opacity: .6; } to { transform: none; opacity: 1; } }

/* Header and footer are flex-fixed; ONLY the middle scrolls. The CTA has to
   be reachable no matter how long the cart gets. */
.sf-dw-hd {
    flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
    padding: 15px 16px; border-bottom: 1px solid var(--sf-line); background: var(--sf-soft);
}
.sf-dw-t { font-family: var(--sf-disp); font-weight: 700; font-size: 17px; color: var(--sf-deep); display: flex; align-items: center; gap: 8px; }
.sf-dw-c {
    font-family: var(--sf-mono); font-size: 10px; font-weight: 500;
    background: var(--sf-deep); color: #fff; border-radius: 20px; padding: 2px 8px;
}
.sf-dw-x {
    width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    background: #fff; color: var(--sf-deep); border: 1px solid var(--sf-line);
}
.sf-dw-x:hover { background: var(--sf-deep); color: #fff; }

.sf-dw-body { flex: 1 1 auto; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }

.sf-dw-empty { text-align: center; padding: 48px 20px; color: var(--sf-muted); }
.sf-dw-empty i { font-size: 2rem; opacity: .4; }
.sf-dw-empty p { margin-top: 10px; font-size: 13px; }

/* ── NAZCA LINE-ITEM CARD ──────────────────────────────────────
   Its own white rounded card with a soft shadow and real padding —
   NOT a flat divider-separated row. Thumbnail in a bordered tile,
   name/variant/qty stacked, price bold right-aligned, trash far right. */
.sf-dw-line {
    /* wrap: the USA Drops badge (.sf-dw-pre) is a FULL-WIDTH row beneath the
       item, not a fourth column. Without this it joined thumb/body/price as a
       flex sibling and squeezed the product name to one letter per line. */
    display: flex; flex-wrap: wrap; gap: 11px; align-items: flex-start;
    background: #fff; border: 1px solid var(--sf-line);
    border-radius: 12px; padding: 11px;
    box-shadow: 0 1px 4px rgba(0,0,0,.05);
}
/* NAZCA'S TILE — the thumbnail is RAISED OUT OF the card, not sunk into it.
   Its own white surface, its own shadow, a hairline border: it reads as an
   object sitting ON the card rather than a hole cut in it. That lift is most
   of why their cart looks expensive. And it is BIGGER — 62px was a stamp; the
   product is the thing being sold, so it gets the room. */
.sf-dw-thumb {
    flex: 0 0 104px; width: 104px; height: 104px; border-radius: 10px;
    border: 1px solid var(--sf-line); background: #fff;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden; padding: 5px; color: var(--sf-muted);
    box-shadow: 0 2px 8px rgba(0,0,0,.10);
}
.sf-dw-thumb img { width: 100%; height: 100%; object-fit: contain; }
/* Belt and braces. The thumb is flex:0 0 104px and CANNOT shrink — yet it kept
   being reported as smaller. The likeliest cause was the missing icon font: a
   product with no photo fell back to <i class="bi bi-bag">, which rendered as an
   empty inline element and collapsed the box. The font is fixed above; these
   floors make the geometry impossible to lose regardless. */
.sf-dw-thumb { min-width: 104px; min-height: 104px; box-sizing: border-box; }
.sf-dw-thumb i { font-size: 26px; line-height: 1; }
button.sf-dw-trash { min-width: 30px; min-height: 30px; box-sizing: border-box; padding: 0; }

.sf-dw-l-b { flex: 1 1 auto; min-width: 0; }
.sf-dw-l-brand { font-family: var(--sf-mono); font-size: 8px; letter-spacing: .07em; text-transform: uppercase; color: var(--sf-muted); }
.sf-dw-l-n {
    font-size: 13px; font-weight: 600; color: var(--sf-ink); line-height: 1.25; margin-top: 2px;
    /* Truncate with an ellipsis — a long SKU name must not shove the price
       out of the rail. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-dw-l-v { font-family: var(--sf-mono); font-size: 9px; color: var(--sf-muted); margin-top: 3px; }

.sf-dw-qty { display: inline-flex; align-items: center; gap: 2px; margin-top: 8px; border: 1px solid var(--sf-line); border-radius: 8px; overflow: hidden; background: var(--sf-bg); }
.sf-dw-qty .q {
    width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
    text-decoration: none; color: var(--sf-deep); font-size: 14px; font-weight: 600; cursor: pointer;
}
.sf-dw-qty .q:hover { background: var(--sf-soft); color: var(--sf-deep); }
.sf-dw-qty .n { min-width: 26px; text-align: center; font-family: var(--sf-mono); font-size: 12px; }

.sf-dw-l-r { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; align-self: stretch; gap: 8px; }
/* The only way to remove a line must always be findable and hittable — an SVG
   (never an icon font) inside a real 30px target, not a 13px glyph. */
.sf-dw-trash {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
    color: var(--sf-muted); background: var(--sf-bg);
    border: 1px solid var(--sf-line); text-decoration: none;
}
.sf-dw-trash:hover { color: #a03030; border-color: #e6c9c9; background: #fdf5f5; }

/* 🔴 THE FORMS I PUT IN THE DRAWER BROUGHT THE BROWSER'S FURNITURE WITH THEM.
   The member's − / + / trash were <a> links; fixing the 405 turned them into
   <form><button>. A <form> is BLOCK-level and a <button> arrives with the UA's
   own font, border and padding — so the quantity stepper grew a second box, the
   row's flex maths changed, and the product thumbnail and the trash both got
   squeezed to make room for chrome nobody asked for.

   The form is plumbing, not layout: it must take no space and impose no style. */
.sf-dw-qty form,
.sf-dw-l-r form {
    display: inline-flex;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
}

/* Buttons must look exactly like the links they replaced. */
.sf-dw-qty button.q,
button.sf-dw-trash {
    font: inherit;
    -webkit-appearance: none;
    appearance: none;
}
.sf-dw-qty button.q {
    border: none;
    background: transparent;
    padding: 0;
}
.sf-dw-l-p { font-family: var(--sf-mono); font-size: 13px; font-weight: 600; color: var(--sf-ink); white-space: nowrap; }

/* Totals — right-aligned figures, dashed rule above the Total. */
.sf-dw-tot { margin-top: 4px; padding: 13px 12px; background: #fff; border: 1px solid var(--sf-line); border-radius: 12px; }
.sf-dw-tot .r { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; color: var(--sf-ink); padding: 3px 0; }
.sf-dw-tot .r span:last-child { font-family: var(--sf-mono); }
.sf-dw-tot .r.total {
    margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--sf-line);
    font-family: var(--sf-disp); font-weight: 700; font-size: 17px; color: var(--sf-deep);
}
.sf-dw-tot .r.total span:last-child { font-family: var(--sf-mono); font-size: 16px; }
.sf-dw-tot .n { font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--sf-muted); margin-top: 8px; }

/* ── USA DROPS · THE TWO-PART PAYMENT ───────────────────────────────────────
   Deliberately quiet. These rows explain a payment SHAPE; they are not a
   promotion and must not out-shout the price they sit beside. The line badge
   is indented under the item so it reads as belonging to that product rather
   than to the cart. */
.sf-dw-pre {
    /* flex-basis 100% + zero left margin: a margin here would push the row past
       the container width, because flex-basis is measured before margins. */
    flex: 0 0 100%;
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
    margin: 2px 0 0; padding: 6px 9px;
    background: #f4f7fb; border: 1px solid #d8e3f0; border-radius: 8px;
    font-size: 11px; color: #2b4a6b; line-height: 1.35;
}
.sf-dw-pre-k {
    font-family: var(--sf-mono); font-size: 8.5px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: #fff; background: #12304c; padding: 2px 6px; border-radius: 4px;
}
.sf-dw-pre b { font-family: var(--sf-mono); font-weight: 700; color: #12304c; }
.sf-dw-pre-eta {
    flex-basis: 100%; font-family: var(--sf-mono);
    font-size: 9.5px; color: var(--sf-muted);
}

/* Sits between Subtotal and Total, so the eye reads: what it costs, how it
   splits, what it comes to. */
.sf-dw-tot .r.sf-dw-split { color: #2b4a6b; font-size: 12px; }
.sf-dw-tot .r.sf-dw-split span:last-child { color: #12304c; font-weight: 600; }

/* "Pagas ahora" — the only figure in the block that leaves her account today,
   so it gets a rule above it and real weight. The rows above sum INTO it; the
   balance below is a separate future event, not part of this payment. */
.sf-dw-tot .r.sf-dw-duenow {
    border-top: 1px solid #d8e3f0; margin-top: 4px; padding-top: 7px;
    color: #12304c; font-size: 13px; font-weight: 700;
}
.sf-dw-tot .r.sf-dw-duenow span:last-child { color: #12304c; font-weight: 700; }

@media (max-width: 520px) {
    .sf-dw-pre { margin-left: 0; }
}

.sf-dw-ft { flex: 0 0 auto; padding: 13px 14px; border-top: 1px solid var(--sf-line); background: var(--sf-bg); }
.sf-dw-go {
    display: flex; align-items: center; justify-content: center; width: 100%;
    padding: 14px; border-radius: 12px; cursor: pointer; text-decoration: none;
    background: var(--sf-deep); color: #fff; border: 1px solid var(--sf-deep);
    font-family: var(--sf-body); font-weight: 600; font-size: 14px;
    transition: filter .15s ease, transform .12s ease;
}
.sf-dw-go:hover { color: #fff; filter: brightness(1.1); transform: translateY(-1px); }
.sf-dw-go.ghost { background: #fff; color: var(--sf-deep); border-color: var(--sf-line); }

/* The trigger. Bottom-right, above everything, with a live count. */
.sf-cartfab {
    position: fixed; right: 18px; bottom: 18px; z-index: 60;
    width: 54px; height: 54px; border-radius: 50%; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    background: var(--sf-deep); color: #fff; border: none;
    box-shadow: 0 6px 20px rgba(0,0,0,.28); font-size: 20px;
}
.sf-cartfab:hover { filter: brightness(1.1); }
.sf-cartfab .fb {
    position: absolute; top: -3px; right: -3px; min-width: 21px; height: 21px;
    border-radius: 11px; background: var(--sf-accent); color: #fff;
    font-family: var(--sf-mono); font-size: 10px; font-weight: 600;
    display: flex; align-items: center; justify-content: center; padding: 0 5px;
    border: 2px solid var(--sf-bg);
}

@media (max-width: 520px) {
    .sf-dw-panel { width: 100%; }   /* the rail becomes the page */
}

/* Small phones (iPhone SE / 360px Android). Her face at 96px plus the gap eats
   112px before her NAME starts, and the name is the thing that has to survive.
   Step the avatar down rather than let the name wrap to three lines. */
@media (max-width: 400px) {
    .sf-brand { gap: 12px; }
    .sf-avatar { width: 78px; height: 78px; border-radius: 18px; }
    .sf-avatar-fallback { font-size: 30px; }
    .sf-bk-times { grid-template-columns: repeat(2, 1fr); }  /* 3 across = 90px buttons */
}

/* ══ LOGIN OVERLAY ═════════════════════════════════════════════
   The first-run language-chooser pattern: the storefront stays visible
   behind a scrim and the card floats over it, wearing HER palette. A
   customer signing in never leaves her page — bouncing them to the
   Identity screen strips her name and her colours off the display at the
   exact moment they commit to buying from her. */
.sf-lo {
    position: fixed; inset: 0; z-index: 95;
    background: rgba(20,14,17,.55); backdrop-filter: blur(5px);
    display: flex; align-items: center; justify-content: center; padding: 20px;
    animation: sfVwIn .16s ease-out;
}
.sf-lo-card {
    position: relative; width: min(400px, 100%);
    background: var(--sf-bg); border: 1px solid var(--sf-line);
    border-radius: 16px; padding: 24px 22px 20px;
    box-shadow: 0 24px 64px rgba(0,0,0,.34);
    animation: sfVwPop .2s cubic-bezier(.2,.8,.3,1);
}
.sf-lo-x {
    position: absolute; top: 12px; right: 12px; width: 32px; height: 32px;
    border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center;
    background: #fff; color: var(--sf-deep); border: 1px solid var(--sf-line);
}
.sf-lo-x:hover { background: var(--sf-deep); color: #fff; }

.sf-lo-hd { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.sf-lo-av { width: 46px; height: 46px; font-size: 19px; }
.sf-lo-t { font-family: var(--sf-disp); font-weight: 700; font-size: 19px; color: var(--sf-deep); line-height: 1.1; }
.sf-lo-s { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-accent); margin-top: 3px; }

.sf-lo-l { display: block; font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-muted); margin: 12px 0 5px; }
.sf-lo-i {
    width: 100%; padding: 11px 12px; border-radius: 10px; font-size: 14px;
    background: #fff; color: var(--sf-ink); border: 1px solid var(--sf-line);
    font-family: var(--sf-body);
}
.sf-lo-i:focus {
    outline: none; border-color: var(--sf-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--sf-accent) 18%, transparent);
}
/* Spacing only — the lockup's own size comes from .sf-powered/.sf-brand-name
   further up, so this stays in step with the Mall and storefront headers
   without restating any of it. Sits above the card's own title block. */
.sf-lo-brand { margin-bottom: 16px; }

.sf-lo-rm { display: flex; align-items: center; gap: 7px; margin-top: 14px; font-size: 12px; color: var(--sf-ink); cursor: pointer; }
.sf-lo-go {
    width: 100%; margin-top: 18px; padding: 13px; border-radius: 12px; cursor: pointer;
    background: var(--sf-deep); color: #fff; border: 1px solid var(--sf-deep);
    font-family: var(--sf-body); font-weight: 600; font-size: 14px;
    transition: filter .15s ease, transform .12s ease;
}
.sf-lo-go:hover { filter: brightness(1.1); transform: translateY(-1px); }
/* Sign-in ⇄ create-account. It is a <button> (it swaps a pane, it does not
   navigate), so the UA chrome has to come off or it renders as a grey box. */
.sf-lo-alt {
    display: block; width: 100%; text-align: center; margin-top: 14px;
    font-size: 12px; color: var(--sf-deep); text-decoration: underline;
    background: none; border: none; padding: 4px; cursor: pointer;
    font-family: inherit;
}
/* First + last name, side by side. They collapse on a narrow phone rather than
   squeezing two inputs into 150px each. */
.sf-lo-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 380px) { .sf-lo-row { grid-template-columns: 1fr; } }

/* ══ THE CARD ON A PHONE ═══════════════════════════════════════════════
   Two separate faults, and only one of them is about size.

   1. The overlay centres the card and NOTHING caps its height. Create
      account is the tallest pane in the app — brand lockup, header, eight
      fields, an account-type hint, a note and two buttons. Once it exceeds
      the viewport, centring pushes equal amounts off the TOP and BOTTOM and
      neither end can be reached: the submit button is unclickable and the
      close button is off-screen. That is not cramped, it is broken, and it
      is why the fix is scrolling the CONTAINER rather than the card — the
      close button lives inside the card and would scroll away with it.

   2. Everything is desktop-sized. The lockup alone costs ~60px above the
      first field, and eight labels at 12px top margin cost ~96px more.

   Galaxy Fold folded is ~280px wide, so the 20px overlay padding was eating
   14% of the screen before anything rendered. ══════════════════════════ */
@media (max-width: 480px) {
    .sf-lo {
        padding: 10px;
        align-items: flex-start;   /* never centre something taller than the screen */
        overflow-y: auto;
    }
    .sf-lo-card { padding: 18px 16px 16px; }

    /* The lockup keeps its proportions, just not its desktop scale. It is
       reassurance at the moment she types a password, not a billboard. */
    .sf-lo-brand { margin-bottom: 10px; }
    .sf-lo-brand .sf-brand-name { font-size: 21px; }
    .sf-lo-brand .sf-powered-k { font-size: 8px; letter-spacing: .16em; }
    .sf-lo-brand .sf-brand-flag svg { width: 17px; height: 11px; }

    .sf-lo-hd { gap: 10px; margin-bottom: 14px; }
    .sf-lo-av { width: 38px; height: 38px; font-size: 16px; }
    .sf-lo-t { font-size: 17px; }

    /* ~8px x 8 labels ≈ 64px recovered, without touching tap targets. */
    .sf-lo-l { margin: 10px 0 4px; }
    .sf-lo-i { padding: 10px 11px; }

    .sf-acct-hint,
    .sf-lo-note { padding: 8px 10px; font-size: 11px; }
    .sf-lo-go { margin-top: 14px; padding: 12px; }
}

/* Fold-class widths. Trim the frame, never the controls — the flag toggle
   stays at 40px so it is still a comfortable thumb target. */
@media (max-width: 360px) {
    .sf-lo { padding: 6px; }
    .sf-lo-card { padding: 14px 12px 12px; border-radius: 14px; }
    .sf-lo-brand .sf-brand-name { font-size: 19px; }
    .sf-lo-hd { margin-bottom: 12px; }
    .sf-lo-av { width: 34px; height: 34px; font-size: 15px; }
    .cc-tog-l { width: 40px; height: 40px; }
}
/* An account is a convenience, never a toll gate — guest checkout is the whole
   doctrine here, and this line is what stops someone bouncing at the sign-up. */
.sf-lo-note {
    margin-top: 14px; padding: 10px 12px; border-radius: 10px;
    background: var(--sf-soft); color: var(--sf-muted);
    font-size: 11.5px; line-height: 1.5;
}

/* The sign-in trigger is a <button> now, not a link — strip UA chrome so it
   still matches the language pills beside it. */
button.sf-mini { cursor: pointer; font-family: var(--sf-mono); }

/* Catalogue toggle — a BUTTON, not a link. It expands the rail; it never
   navigates away from her storefront. */
.sf-catalog-card { cursor: pointer; font-family: var(--sf-body); }
.sf-catalog-card.on { background: var(--sf-deep); border-style: solid; border-color: var(--sf-deep); color: #fff; }
.sf-catalog-card.on .cc-s { color: rgba(255,255,255,.72); }

/* ── HER SHELF | THE REST OF THE CATALOGUE ────────────────────
   A hard visual break in the rail. Left of it: products she chose, uses,
   and put her name on. Right of it: stock. Blurring the two silently
   downgrades her endorsement to a shrug — and her endorsement is the only
   reason anyone is reading this page. */
.sf-cat-sep {
    flex: 0 0 auto; align-self: stretch; width: 34px;
    display: flex; align-items: center; justify-content: center;
    border-left: 2px dashed var(--sf-line);
    margin-left: 4px;
}
.sf-cat-sep .cs-l {
    writing-mode: vertical-rl; transform: rotate(180deg);
    font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--sf-muted); white-space: nowrap;
}
/* Catalogue stock — the SAME clean white well as her recommended products, so a
   white-background product photo blends instead of floating as a tinted square.
   It's still marked as ValoraFi catalogue (not a personal recommendation), but by
   a subtly deeper OUTLINE rather than the old tinted fill. Theme-aware via
   color-mix; the plain hex above it is the fallback for browsers without it. */
.sf-prod.cat {
    background: #fff;
    border-color: #ddd0cb;
    border-color: color-mix(in srgb, var(--sf-deep) 22%, transparent);
}
.sf-prod.cat .sf-prod-img { background: #fff; }

/* Guest cart controls are FORMS (anonymous cart writes need antiforgery), so
   the buttons inside them must look exactly like the links they replace. */
.sf-add-f { display: flex; }
button.sf-prod-add { font: inherit; }
.sf-dw-qty form { display: flex; margin: 0; }
button.sf-dw-qty-q, .sf-dw-qty button.q { background: none; border: none; font: inherit; }
form:has(> button.sf-dw-trash) { margin: 0; display: flex; }
button.sf-dw-trash { background: none; border: none; cursor: pointer; font: inherit; }

/* 🔴 CLOSE BUTTONS DRAW A REAL CHARACTER, NOT AN ICON-FONT GLYPH.
   <i class="bi bi-x-lg"> renders as NOTHING when bootstrap-icons fails to
   load — a bride on bad mobile data, which is exactly our reader. Every
   modal on this page then becomes a trap: no visible way out. Same root
   cause as the invisible "+" on the buy button. A literal × always paints. */
.xg { font-size: 20px; line-height: 1; font-weight: 400; display: block; margin-top: -2px; }
.sf-vw-x .xg, .sf-dw-x .xg, .sf-lo-x .xg { font-size: 22px; }

/* AURA CARD — hover plays, click opens. Knowledge-index grammar. */
.sf-vcard { position: relative; cursor: pointer; }
.sf-vcard .vthumb { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity .25s, transform .35s; }
.sf-vcard:hover .vthumb { transform: scale(1.04); }
.sf-vcard .vhover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .3s; background: #000; }
.sf-vcard.is-playing .vhover { opacity: 1; }
.sf-vcard.is-playing .vthumb { opacity: 0; }
.sf-vcard.is-playing .vplay { opacity: 0; }
/* A real character, never an icon font — same rule as the + and the ×. */
.sf-vcard .vplay {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
    width: 44px; height: 44px; border-radius: 50%; z-index: 3;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0,.45); color: #fff; font-size: 15px;
    transition: opacity .2s, background .2s; pointer-events: none;
}
.sf-vcard:hover .vplay { background: color-mix(in srgb, var(--sf-accent) 85%, #000); }
/* The pills are LINKS and must win the click over the card. */
.sf-vcard .vpills { z-index: 5; }
a.sf-vpill { text-decoration: none; pointer-events: auto; }

/* ══ GUEST CHECKOUT — /store/{handle}/pagar ═══════════════════
   Her palette, right through the moment they pay. */
.sf-co { max-width: 980px; margin: 0 auto; padding: 18px 16px 48px; }
.sf-co-t { font-family: var(--sf-disp); font-size: 26px; color: var(--sf-deep); margin: 14px 0 18px; }
.sf-co-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 20px; align-items: start; }
.sf-co-card { background: #fff; border: 1px solid var(--sf-line); border-radius: 14px; padding: 18px; margin-bottom: 14px; }
.sf-co-h { font-family: var(--sf-disp); font-size: 16px; color: var(--sf-deep); margin: 0 0 10px; }
.sf-co-hint { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .04em; color: var(--sf-muted); margin-top: 6px; }

/* Flag picker beside the number. The code is a narrow fixed column so the
   number — the part she is actually typing — keeps the width. */
.sf-lo-phone { display: flex; gap: 8px; align-items: stretch; }
/* The country picker is now a two-flag radio group (_CountryToggle), not a
   select. It sizes itself; it just must not stretch or shrink beside the
   number field. currentColor drives the selected ring, so it inherits the
   overlay's ink rather than naming a palette variable. */
.sf-lo-phone .cc-tog { flex: 0 0 auto; color: var(--sf-accent); }
.sf-lo-phone .cc-tog-l { height: 42px; }
.sf-lo-phone input { flex: 1 1 auto; min-width: 0; }

/* ── SELECTS IN THE OVERLAY ───────────────────────────────────────────
   A bare <select> inherits the OS widget: grey chrome, a native arrow, a
   different height from every input beside it. On a form a professional is
   judging the product by, that one control makes the whole card look
   unfinished. Match the text inputs exactly, then draw our own chevron. */
select.sf-lo-i {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6058' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 15px 15px;
    padding-right: 34px;
    cursor: pointer;
    /* Long option text (the account-type descriptions) must not stretch the
       card — the closed control truncates, the open list still reads in full. */
    text-overflow: ellipsis;
}
select.sf-lo-i:focus { outline: none; border-color: var(--sf-accent); box-shadow: 0 0 0 3px rgba(160,120,32,.16); }
/* The option text is now just the dial code — the flag is an SVG background
   from country-flags.css. font-variant-emoji is deliberately NOT set here:
   it forced text presentation, which is what turned 🇨🇴 into "co". */
.sf-lo-phone .sf-lo-cc { letter-spacing: .01em; }

/* ── ACCOUNT TYPE ─────────────────────────────────────────────────────
   A chosen value, not placeholder prose. The control carries the noun at
   the weight of an answer; the explanation lives below so a 380px card
   never has to fit "Professional — I provide beauty, wellness or related
   services" between two rounded corners. */
select.sf-lo-acct { font-weight: 600; }

/* Tinted rather than bordered: it is a consequence of the choice above, not
   a field of its own, and a second box outline here would read as another
   input. Sits tight under the select so the pairing is unambiguous. */
.sf-acct-hint {
    margin-top: 8px; padding: 10px 12px; border-radius: 10px;
    background: var(--sf-soft); color: var(--sf-muted);
    font-size: 11.5px; line-height: 1.55;
}
.sf-acct-hint p { margin: 0; }
/* The title is the only part that must survive a skim — "requires
   verification" is the one thing a trade applicant needs to see before
   submitting, not after. */
.sf-acct-hint strong { color: var(--sf-ink); font-weight: 600; }

/* The field that was actually rejected. The error summary sits at the top of the
   form and scrolls out of view the moment she starts correcting things, so the
   input has to carry the state too. Colour is not the only signal — the summary
   names the field in words, and aria-invalid carries it to a screen reader. */
.sf-lo-i.is-bad {
    border-color: #b3261e;
    background: rgba(179,38,30,.04);
}
.sf-lo-i.is-bad:focus { outline: none; border-color: #b3261e; box-shadow: 0 0 0 3px rgba(179,38,30,.14); }
.sf-co-note { font-size: 13px; line-height: 1.55; color: var(--sf-ink); background: var(--sf-soft); border-radius: 10px; padding: 11px 12px; margin-top: 12px; }
.sf-co-err { background: #fdf4f4; border: 1px solid #e8cccc; color: #a03030; border-radius: 10px; padding: 11px 13px; font-size: 13px; margin-bottom: 14px; }

/* ══ MOBILE: A GRID, NOT AN ENDLESS STRIP ══════════════════════════════
   A horizontal rail is a good way to show FIVE things and a terrible way to
   show five hundred. On a phone it is worse than terrible: the customer sees
   two products, has no idea how many more exist, and has to swipe blind. With
   587 SKUs in production that is not a browsing experience, it is a treadmill.

   On mobile the rails become a two-up grid. Same card, same image size (which
   he likes), but she can SEE the shelf instead of feeling along it. And the
   "see full catalogue" tile lands naturally as the last cell instead of being
   flung to the end of a scroll nobody reaches.

   Desktop keeps the rail — there, a horizontal row is elegant and the whole
   thing is visible at once.

   The cap is deliberate: six, then "ver más". An un-capped grid of 587 products
   is a page that never ends, and a page that never ends is a page you leave. */
@media (max-width: 899px) {
    .sf-prow.sf-rail,
    .sf-vrow.sf-rail {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 11px;
        overflow-x: visible;
        scroll-snap-type: none;
        /* undo the rail's bleed — a grid must not hang off the page edge */
        margin-left: 0; margin-right: 0;
        padding-left: 0; padding-right: 0;
    }

    /* The cards were sized for a rail (flex: 0 0 194px). In a grid they take
       the cell. */
    .sf-prow.sf-rail > .sf-prod,
    .sf-prow.sf-rail > .sf-catalog-card,
    .sf-vrow.sf-rail > .sf-vcard {
        flex: initial;
        width: auto;
        min-width: 0;                 /* or long product names blow the column out */
        scroll-snap-align: none;
    }

    /* The catalogue separator is a rail device. In a grid it is noise. */
    .sf-prow.sf-rail > .sf-cat-sep { display: none !important; }

    /* CAPPED until she asks for more. `.cat` items are the hidden catalogue —
       they have their own toggle and must not be counted here. */
    .sf-prow.sf-rail:not(.is-more) > .sf-prod:not(.cat) ~ .sf-prod:not(.cat) ~ .sf-prod:not(.cat)
        ~ .sf-prod:not(.cat) ~ .sf-prod:not(.cat) ~ .sf-prod:not(.cat) { display: none; }

    .sf-vrow.sf-rail:not(.is-more) > .sf-vcard ~ .sf-vcard ~ .sf-vcard
        ~ .sf-vcard ~ .sf-vcard ~ .sf-vcard { display: none; }
}

/* ── REVIEWS: capped, both viewports ──────────────────────────────────
   Six on desktop, three on the phone. An unbounded wall of reviews pushes the
   things she can actually buy off the bottom of the page — and reviews are
   proof, not the product. Unlike the rails, this cap applies on DESKTOP too,
   so its button is visible at every width. */
.sf-rev-grid:not(.is-more) > .sf-rev:nth-of-type(n+7) { display: none; }

@media (max-width: 899px) {
    .sf-rev-grid:not(.is-more) > .sf-rev:nth-of-type(n+4) { display: none; }
}

.sf-more--rev {
    display: flex !important;        /* the rails' button is mobile-only; this is not */
    align-items: center; justify-content: center; gap: 6px;
    width: 100%;
    margin-top: 14px;
    padding: 11px;
    border-radius: 11px;
    border: 1px solid var(--sf-line);
    background: #fff;
    color: var(--sf-deep);
    font-family: var(--sf-body); font-size: 12.5px; font-weight: 600;
    cursor: pointer;
}
.sf-more--rev:hover { background: var(--sf-soft, #faf7f3); }

/* The "ver más" control. Desktop never needs it — the rail shows everything. */
.sf-more { display: none; }
@media (max-width: 899px) {
    .sf-more {
        display: flex; align-items: center; justify-content: center; gap: 6px;
        width: 100%;
        margin-top: 12px;
        padding: 11px;
        border-radius: 11px;
        border: 1px solid var(--sf-line);
        background: #fff;
        color: var(--sf-deep);
        font-family: var(--sf-body); font-size: 12.5px; font-weight: 600;
        cursor: pointer;
    }
    .sf-more:hover { background: var(--sf-soft, #faf7f3); }
    .sf-more .cv { transition: transform .18s ease; font-size: 11px; }
    .sf-more.is-open .cv { transform: rotate(180deg); }
}

/* ══ THE VIDEO'S ACTIONS, AND THE PRODUCTS INSIDE IT ═══════════════════
   The shortest path to a sale on this entire storefront: she watches her
   stylist use something, and asks "what is that?" — and now the answer is a
   card with a + on it, over the video she is already watching.

   The panel slides OVER the player. The video never reloads, never re-buffers,
   never loses its place. If she changes her mind it is still there. */
.sf-vw-video { position: relative; }

/* 🔴 THE NATIVE CONTROL BAR OWNS THE BOTTOM OF A <video>. STAY OFF IT.
   BOOK and SHOP were at bottom-left and the icon rail at bottom-right — which is
   exactly where the browser paints play, scrub, volume, fullscreen and the kebab.
   Every one of our controls was sitting on top of a control the browser had
   already claimed, so both were unusable and neither was our bug to fix in the
   browser. The bottom strip is not ours.

   BOOK / SHOP go to the TOP. The icon rail goes to the RIGHT EDGE, vertically
   centred, well above the bar. Nothing we draw touches the bottom 64px. */
.sf-vw-acts-bar {
    position: absolute;
    left: 12px; top: 12px;
    display: flex; gap: 8px;
    z-index: 4;
}
.sf-vw-cta {
    border: none; cursor: pointer;
    font-family: var(--sf-body);
    font-size: 12.5px; font-weight: 700;
    letter-spacing: .02em;
    padding: 9px 16px;
    border-radius: 999px;
    box-shadow: 0 3px 12px rgba(0,0,0,.28);
    transition: filter .14s ease, transform .12s ease;
}
.sf-vw-cta:hover { filter: brightness(1.12); transform: translateY(-1px); }
.sf-vw-cta.b { background: var(--sf-deep); color: #fff; }
.sf-vw-cta.s { background: var(--sf-accent); color: #fff; }

/* ── THE ICON RAIL ────────────────────────────────────────────────────
   Right edge, vertical, thumb-reachable. The Aura feed's grammar, brought onto
   her storefront so a video behaves the same way wherever the customer meets it.
   A guest tapping ❤ or 🔖 gets the login overlay — the account earns its way in
   at the one moment she actually wants something. */
/* Right edge, vertically centred, clear of the native control bar at the bottom
   and of BOOK/SHOP at the top. This is the TikTok grammar and it is the only
   place on a video that belongs to the app rather than to the browser. */
.sf-vw-rail {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    display: flex; flex-direction: column; gap: 12px;
    z-index: 4;
    transition: top .22s ease, transform .22s ease, opacity .18s ease;
}

/* 🔴 THE RAIL AND THE PRODUCT SHEET WERE FIGHTING FOR THE SAME CORNER.
   The sheet rises from the bottom to 72% of the video; the rail sits at 50%.
   So the like/save/views icons landed ON TOP of the products — an icon
   overlapping a price is worse than an icon you cannot see.

   While she is shopping, the products are the subject. The rail lifts clear and
   goes quiet; it comes back the moment she closes the sheet. Nothing is
   removed, so the counts do not flicker. */
.sf-vw-video.is-shopping .sf-vw-rail {
    top: 14px;
    transform: translateY(0);
    opacity: .55;
    flex-direction: row;       /* along the top, not down the side she is reading */
    right: 12px;
}
.sf-vw-video.is-shopping .sf-vw-rail:hover { opacity: 1; }
.sf-vwr {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    min-width: 42px;
    padding: 7px 4px;
    border: none;
    border-radius: 12px;
    background: rgba(20,18,16,.42);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: #fff;
    cursor: pointer;
    transition: background .14s ease, transform .12s ease;
}
.sf-vwr i { font-size: 17px; line-height: 1; }
.sf-vwr .n {
    font-family: var(--sf-mono);
    font-size: 9.5px;
    letter-spacing: .02em;
}
.sf-vwr:hover { background: rgba(20,18,16,.6); transform: translateY(-1px); }
.sf-vwr.on { color: #ff5a76; }              /* liked */
.js-vw-save.on { color: var(--sf-accent); } /* saved */
/* Views are a fact, not a button. It must not look tappable. */
.sf-vwr--stat { cursor: default; }
.sf-vwr--stat:hover { background: rgba(20,18,16,.42); transform: none; }

/* The product panel. Bottom sheet — thumb country on a phone, and it never
   covers the face of the video, only its lower half. */
.sf-vshop {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    max-height: 72%;
    display: flex; flex-direction: column;
    background: var(--sf-bg, #fff);
    border-top: 1px solid var(--sf-line);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -8px 30px rgba(0,0,0,.22);
    z-index: 3;
    animation: sf-vshop-up .22s ease;
}
@keyframes sf-vshop-up { from { transform: translateY(14px); opacity: 0; } }

.sf-vshop-hd {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 14px 10px;
    border-bottom: 1px solid var(--sf-line);
    font-family: var(--sf-mono);
    font-size: 10px; letter-spacing: 1.3px; text-transform: uppercase;
    color: var(--sf-ink-3, #9a8f83);
}
.sf-vshop-x {
    background: none; border: none; cursor: pointer;
    font-size: 22px; line-height: 1;
    color: var(--sf-ink-3, #9a8f83);
    padding: 0 2px;
}
.sf-vshop-x:hover { color: var(--sf-ink); }

.sf-vshop-body { flex: 1 1 auto; overflow-y: auto; padding: 12px 14px 16px; }

.sf-vshop-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
    gap: 12px;
}

/* 🔴 THE SHOP SHEET, MOBILE — placed AFTER the base .sf-vshop rules ON PURPOSE.
   An identical override earlier in the file (in the fullscreen @media block) was
   being beaten by these base rules on source order, so the sheet stayed at 72%
   of the video and only ~2 products fit. Here it wins: the sheet takes nearly
   the whole screen so at least FOUR products show in two columns — the product
   card/image size is unchanged. dvh (not %) so the height is definite even if the
   video's flex height doesn't resolve. */
@media (max-width: 640px) {
    /* Leave a fixed 60px clear at the top of the video so the BOOK / SHOP
       buttons and the like/save/views icons stay visible ABOVE the sheet — the
       sheet starts right below them and fills the rest (still ~4 products). */
    .sf-vshop { height: calc(100% - 60px); max-height: calc(100% - 60px); }
    .sf-vshop-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .sf-vshop-body { padding: 12px 14px 20px; }
}
.sf-vshop-card {
    display: flex; flex-direction: column;
    border: 1px solid var(--sf-line);
    border-radius: 12px;
    overflow: hidden;
    background: #fff;
}
.sf-vshop-card.oos { opacity: .62; }
.sf-vshop-img { display: block; aspect-ratio: 1 / 1; background: var(--sf-soft, #faf7f3); }
.sf-vshop-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-vshop-b { padding: 9px 10px 10px; display: flex; flex-direction: column; flex: 1 1 auto; }
.sf-vshop-brand {
    font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--sf-ink-3, #9a8f83);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sf-vshop-n {
    font-size: 12.5px; line-height: 1.3; color: var(--sf-ink);
    margin-top: 2px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.sf-vshop-p {
    font-family: var(--sf-mono); font-size: 13px; color: var(--sf-ink);
    margin-top: auto; padding-top: 8px;
}
.sf-vshop-add {
    margin-top: 8px;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    width: 100%;
    padding: 8px 6px;
    border-radius: 9px;
    border: 1px solid color-mix(in srgb, var(--sf-accent) 80%, #000);
    background: var(--sf-accent);
    color: #fff;
    font-family: var(--sf-body); font-size: 11.5px; font-weight: 700;
    cursor: pointer;
    transition: filter .14s ease;
}
.sf-vshop-add:hover { filter: brightness(1.1); }
.sf-vshop-add .pl { font-size: 15px; line-height: 1; }
.sf-vshop-oos {
    margin-top: 8px; text-align: center;
    font-family: var(--sf-mono); font-size: 9px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    color: #a03030; background: #f4f1f1;
    border: 1px solid #e6dcdc; border-radius: 9px;
    padding: 7px 6px;
}

/* ══ MI ACTIVIDAD ══════════════════════════════════════════════════════
   Her account, in the drawer. The TODOs come first and they are the loudest
   thing on the panel, because a confirmation and a review are the professional's
   PROOF — the thing that books her next client — and they only ever get written
   if the customer is asked somewhere she actually looks. */
/* The drawer is the surface that handles money, and it read like a list. A
   customer decides whether to trust a checkout in about a second, and she
   decides it on how it LOOKS before she has read a word. */
.sf-act-hd {
    margin-bottom: 16px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--sf-line);
}
.sf-act-hi {
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 22px;
    color: var(--sf-ink);
    line-height: 1.2;
    letter-spacing: -.01em;
}
.sf-act-sub {
    margin-top: 5px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--sf-ink-2, #6b6058);
}

.sf-act-sec {
    font-family: var(--sf-mono);
    font-size: 9px; letter-spacing: 1.3px; text-transform: uppercase;
    color: var(--sf-ink-3, #9a8f83);
    margin: 18px 0 8px;
}

/* ── YOU AND HER ──────────────────────────────────────────────────────
   The relationship, as a number. "4 services · 3 orders · $220.000" is a
   sentence about a person, not a list of receipts — and it is the reason she
   comes back. The card for THIS store is the loud one; she is standing in it. */
.sf-act-stats {
    border: 1px solid var(--sf-line);
    border-radius: 14px;
    padding: 12px 14px 13px;
    margin-bottom: 10px;
    background: #fff;
}
.sf-act-stats.mine {
    background: var(--sf-soft, #faf7f3);
    border-color: var(--sf-accent);
}
.sf-act-stats-hd {
    font-family: var(--sf-mono);
    font-size: 9px; letter-spacing: 1.2px; text-transform: uppercase;
    color: var(--sf-ink-3, #9a8f83);
    margin-bottom: 10px;
}
.sf-act-stats.mine .sf-act-stats-hd { color: var(--sf-accent); }

.sf-act-stats-row { display: flex; align-items: stretch; }
.sf-act-stats-row .s {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
    padding: 0 4px;
}
.sf-act-stats-row .s + .s { border-left: 1px solid var(--sf-line); }
.sf-act-stats-row .v {
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 18px;
    color: var(--sf-ink);
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sf-act-stats-row .k {
    font-family: var(--sf-mono);
    font-size: 8.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--sf-ink-3, #9a8f83);
    margin-top: 4px;
}

/* SHE OWES THIS. Amber, because it is an ask — not an error, not a boast. */
.sf-act-todo {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 12px;
    margin-bottom: 8px;
    border-radius: 11px;
    background: #fff8e6;
    border: 1px solid #f0d69a;
    border-left: 3px solid #d99b1c;
}
.sf-act-todo.mine { border-left-color: var(--sf-accent); }
.sf-act-todo-b { flex: 1 1 auto; min-width: 0; }
.sf-act-todo-t {
    font-size: 13px; font-weight: 600; color: #6b4d0c;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sf-act-todo-s { font-size: 11.5px; color: #8a6a1c; margin-top: 1px; }
.sf-act-cta {
    flex: 0 0 auto;
    padding: 7px 13px;
    border-radius: 999px;
    background: var(--sf-deep);
    color: #fff;
    font-family: var(--sf-body); font-size: 11.5px; font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}
.sf-act-cta:hover { color: #fff; filter: brightness(1.15); }

/* ── PROVIDER open-step rows — the OWNER's actions. Cooler than the customer's
   gold "you owe" rows so the two legs read apart at a glance. ── */
.sf-act-todo.prov { background: #eef3f8; border-color: #cfe0ee; border-left-color: var(--sf-deep); }
.sf-act-todo.prov .sf-act-todo-t { color: #1a3a5c; }
.sf-act-todo.prov .sf-act-todo-s { color: #5a7186; }
.sf-act-todo.prov.pay { background: #eaf5ef; border-color: #bfe0cf; border-left-color: #1f6b53; }
.sf-act-stepf { margin: 0; flex: 0 0 auto; }
.sf-act-stepf button { cursor: pointer; border: none; }
/* the money action — "did the money land?" and the order Pay CTA — reads as settlement (green). */
.sf-act-cta.pay { background: #1f6b53; }

/* ══ ORDERS ⚡ DRAWER — one card per past order; Reorder → cart drawer ══ */
.sf-ord { border: 1px solid var(--sf-line); border-radius: 12px; padding: 12px; margin-bottom: 10px; background: #fff; }
.sf-ord.mine { border-left: 3px solid var(--sf-accent); }
.sf-ord-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.sf-ord-when { font-family: var(--sf-mono); font-size: 11px; color: var(--sf-muted); }
.sf-ord-total { font-family: var(--sf-mono); font-size: 15px; font-weight: 600; color: var(--sf-deep); }
.sf-ord-presc { font-family: var(--sf-mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-accent); margin-top: 3px; }
.sf-ord-lines { margin: 9px 0 11px; display: flex; flex-direction: column; gap: 10px; }
.sf-ord-line { display: flex; align-items: center; gap: 11px; }
/* Product-forward, same doctrine as the cart drawer's raised tile: the thing being
   sold gets the room. Lifted off the card (own surface, hairline, soft shadow) so
   she recognises the bottle before she reads the name. */
.sf-ord-thumb {
    flex: 0 0 60px; width: 60px; height: 60px; border-radius: 10px; overflow: hidden;
    background: #fff; border: 1px solid var(--sf-line); display: flex;
    align-items: center; justify-content: center; padding: 4px;
    box-shadow: 0 2px 8px rgba(0,0,0,.09);
}
.sf-ord-thumb img { width: 100%; height: 100%; object-fit: contain; }
.sf-ord-l-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.sf-ord-l-brand { font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-muted); }
.sf-ord-l-name { font-size: 12.5px; color: var(--sf-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sf-ord-l-q { font-family: var(--sf-mono); font-size: 11px; color: var(--sf-muted); flex: 0 0 auto; }
.sf-ord-l-p { font-family: var(--sf-mono); font-size: 12px; color: var(--sf-ink); flex: 0 0 auto; min-width: 62px; text-align: right; }
.sf-ord-acts { display: flex; gap: 8px; }
.sf-ord-view { flex: 0 0 auto; padding: 9px 14px; border-radius: 10px; border: 1px solid var(--sf-line); background: #fff; color: var(--sf-deep); font-family: var(--sf-body); font-size: 12px; font-weight: 600; text-decoration: none; display: inline-flex; align-items: center; }
.sf-ord-view:hover { border-color: var(--sf-deep); color: var(--sf-deep); text-decoration: none; }
.sf-ord-re-f { margin: 0; flex: 1 1 auto; display: flex; }
.sf-ord-re { width: 100%; padding: 9px 14px; border-radius: 10px; border: none; cursor: pointer; background: var(--sf-deep); color: #fff; font-family: var(--sf-body); font-size: 12px; font-weight: 700; }
.sf-ord-re:hover { filter: brightness(1.12); }
.sf-ord-re[disabled] { background: var(--sf-soft); color: var(--sf-muted); cursor: default; }
.sf-ord-re[disabled]:hover { filter: none; }

/* ── USA DROPS · PAY THE BALANCE, FROM THE ORDERS PANEL ──────────────────
   Its OWN row under the actions, full width. Reorder is a browse action and
   this is a money action; sharing a line with "buy it again" puts a second
   order one mis-tap away from a payment.

   Green (#1f6b53) because that is already what settlement wears on the
   Activity panel's .sf-act-cta.pay — the same act should not change colour
   because it is on a different panel. Navy would collide with Reorder. */
.sf-ord-acts--pay { margin-top: 8px; }
.sf-ord-pay {
    width: 100%; padding: 10px 14px; border-radius: 10px; border: none;
    background: #1f6b53; color: #fff; cursor: pointer; text-align: center;
    font-family: var(--sf-body); font-size: 12.5px; font-weight: 700;
    text-decoration: none; display: block;
}
.sf-ord-pay:hover { color: #fff; text-decoration: none; filter: brightness(1.12); }
/* Sent, not settled — same treatment the Activity panel uses for the wait. */
.sf-ord-pay.is-waiting {
    background: #eef6f1; color: #1f6b53; border: 1px solid #cfe6da;
    cursor: default; pointer-events: none; font-weight: 600;
}

/* Price drift + agotado. She must SEE a moved price and an excluded line before
   she taps — a reorder that re-prices or drops a line silently is unforgivable. */
.sf-ord-line.oos { opacity: .5; }
.sf-ord-l-oos { font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-muted); margin-top: 2px; }
.sf-ord-l-was { display: block; font-size: 10px; color: var(--sf-muted); text-decoration: line-through; }
.sf-ord-l-now { display: block; }
.sf-ord-drift { font-family: var(--sf-mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-accent); margin: -4px 0 9px; }

/* History. Quiet — it is a record, not a call to action. */
.sf-act-row {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    margin-bottom: 6px;
    border-radius: 11px;
    border: 1px solid var(--sf-line);
    background: #fff;
    text-decoration: none;
    color: inherit;
}
a.sf-act-row:hover { border-color: var(--sf-accent); }

/* Bought through THIS professional. The sale the customer caused — and the only
   place she will ever see that she caused it. */
.sf-act-row.mine { background: var(--sf-soft, #faf7f3); border-color: var(--sf-accent); }

.sf-act-row-b { flex: 1 1 auto; min-width: 0; }
.sf-act-row-t {
    font-size: 13px; color: var(--sf-ink);
    display: flex; align-items: center; gap: 6px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sf-act-row-s {
    font-family: var(--sf-mono); font-size: 10.5px;
    color: var(--sf-ink-3, #9a8f83); margin-top: 2px;
}
.sf-act-row-r { flex: 0 0 auto; text-align: right; }
.sf-act-row-p { font-family: var(--sf-mono); font-size: 12.5px; color: var(--sf-ink); }
.sf-act-row-st {
    font-family: var(--sf-mono); font-size: 9px; letter-spacing: .06em;
    text-transform: uppercase; color: var(--sf-ink-3, #9a8f83); margin-top: 2px;
}

.sf-act-tag {
    flex: 0 0 auto;
    font-family: var(--sf-mono); font-size: 8.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    padding: 2px 6px; border-radius: 999px;
}
.sf-act-tag.up { background: var(--sf-blue-soft, #e8f0f8); color: #1a3a5c; }
.sf-act-tag.me { background: var(--sf-accent); color: #fff; }

/* ── UNCLAIMED GUEST ACTIVITY ─────────────────────────────────────────
   An amber notice, not a red error and not a grey aside. Nothing is wrong
   and nothing is lost — there is simply one step left, and the tone has to
   say that. Red would frighten a customer about bookings that are perfectly
   safe; grey would let her scroll past the reason her totals look short. */
.sf-act-claim {
    margin: 0 0 14px;
    padding: 12px 14px;
    border-radius: 11px;
    background: rgba(245,158,11,.10);
    border: 1px solid rgba(245,158,11,.42);
}
.sf-act-claim-t {
    font-family: var(--sf-body); font-weight: 700; font-size: 13.5px;
    color: #78350f; line-height: 1.3;
}
.sf-act-claim-s {
    font-size: 12.5px; color: #78350f; opacity: .9;
    line-height: 1.45; margin-top: 3px;
}
/* Two answers, weighted. Claiming is the likely one and gets the solid button;
   "not mine" is real but rarer, so it is present and legible without being
   offered as an equal choice. Actions sit on their own row, full width on a
   phone — a professional reads this between clients, one-handed. */
.sf-act-claim-acts {
    display: flex; align-items: center; gap: 8px;
    margin-top: 13px; padding-top: 12px;
    border-top: 1px solid rgba(120,53,15,.16);
    flex-wrap: wrap;
}
.sf-act-claim-gof { margin: 0; flex: 1 1 auto; }
.sf-act-claim-go {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    width: 100%; appearance: none; cursor: pointer;
    padding: 10px 16px; border-radius: 10px;
    background: #78350f; border: 1px solid #78350f; color: #fff;
    font-family: var(--sf-body); font-size: 13px; font-weight: 700;
    letter-spacing: .01em; text-decoration: none;
    min-height: 42px; line-height: 1.2;
    box-shadow: 0 1px 2px rgba(120,53,15,.22);
    transition: background .14s ease, box-shadow .14s ease, transform .06s ease;
}
.sf-act-claim-go:hover { background: #5f2a0b; border-color: #5f2a0b; color: #fff; box-shadow: 0 2px 8px rgba(120,53,15,.28); }
.sf-act-claim-go:active { transform: translateY(1px); box-shadow: none; }
.sf-act-claim-go svg { flex: none; opacity: .9; }

.sf-act-claim-nof { margin: 0; flex: 0 0 auto; }
.sf-act-claim-no {
    appearance: none; background: none; cursor: pointer;
    padding: 10px 12px; min-height: 42px;
    border: 1px solid transparent; border-radius: 10px;
    font-family: var(--sf-body); font-size: 12.5px; font-weight: 600;
    color: #8a5a2b;
}
.sf-act-claim-no:hover { color: #5f2a0b; border-color: rgba(120,53,15,.28); background: rgba(120,53,15,.05); }

/* Full width, stacked, on a narrow drawer — 42px targets side by side get
   cramped below ~360px and the secondary action starts collecting mis-taps. */
@media (max-width: 380px) {
    .sf-act-claim-acts { flex-direction: column; align-items: stretch; }
    .sf-act-claim-nof, .sf-act-claim-no { width: 100%; }
}

.sf-act-empty { padding: 26px 12px; text-align: center; }
.sf-act-empty-t { font-size: 13px; color: var(--sf-ink-2, #6b6058); }

/* ── HER FACE, ON EVERY ROW ────────────────────────────────────────────
   A customer does not remember "booking 4b01be5d". She remembers the woman who
   did her hair. A row with a face is a person she owes an answer to; a row with
   a platform label is a thing to scroll past. This is the recognition the whole
   compound-interest thesis runs on. */
.sf-act-av {
    flex: 0 0 auto;
    width: 38px; height: 38px;
    border-radius: 11px;
    overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    background: var(--sf-soft, #faf7f3);
    border: 1px solid var(--sf-line);
    color: var(--sf-ink-3, #9a8f83);
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 14px;
}
.sf-act-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-act-av.sm { width: 32px; height: 32px; border-radius: 9px; font-size: 12px; }

/* THE DOT. Nobody presses a profile icon speculatively — this is the reason to. */
.sf-mini--icon { position: relative; overflow: visible; }
.sf-act-dot {
    position: absolute;
    top: -3px; right: -3px;
    min-width: 15px; height: 15px;
    padding: 0 3px;
    border-radius: 999px;
    background: #d94040;
    color: #fff;
    font-family: var(--sf-mono);
    font-size: 8.5px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
    border: 1.5px solid #fff;
}

/* ── CONFIRM, IN THE DRAWER ────────────────────────────────────────────
   The confirmation is the professional's PROOF. It happens where the customer
   already is, never by ejecting her into ValoraFi at the moment she is about to
   vouch for someone. */
.sf-cf-back {
    display: inline-flex; align-items: center; gap: 5px;
    margin-bottom: 14px;
    padding: 5px 10px 5px 7px;
    border-radius: 999px;
    border: 1px solid var(--sf-line);
    background: #fff;
    color: var(--sf-ink-2, #6b6058);
    font-family: var(--sf-body); font-size: 11.5px; font-weight: 600;
    cursor: pointer;
}
.sf-cf-back:hover { border-color: var(--sf-accent); color: var(--sf-deep); }

.sf-cf-hd { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.sf-cf-av {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    border-radius: 14px;
    overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    background: var(--sf-soft, #faf7f3);
    border: 1px solid var(--sf-line);
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 18px;
    color: var(--sf-ink-3, #9a8f83);
}
.sf-cf-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sf-cf-svc {
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 17px; color: var(--sf-ink); line-height: 1.25;
}
.sf-cf-pro { font-size: 12.5px; color: var(--sf-ink-2, #6b6058); margin-top: 2px; }

.sf-cf-facts {
    border: 1px solid var(--sf-line);
    border-radius: 12px;
    padding: 11px 13px;
    background: #fff;
}
.sf-cf-facts .r {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 4px 0;
    font-size: 12.5px;
}
.sf-cf-facts .r span:first-child { color: var(--sf-ink-3, #9a8f83); }
.sf-cf-facts .r span:last-child { color: var(--sf-ink); font-family: var(--sf-mono); font-size: 12px; }

.sf-cf-ask {
    margin-top: 18px;
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 17px;
    color: var(--sf-ink);
    line-height: 1.3;
}
.sf-cf-sub { margin-top: 4px; font-size: 12.5px; color: var(--sf-ink-2, #6b6058); line-height: 1.5; }

/* Disputing is NOT a one-tap button. It is a serious act with consequences for
   her money and the professional's record, and it belongs on the full page where
   the whole context is visible. Making it as easy as "yes" would make it as
   casual as "yes". */
.sf-cf-dispute {
    display: block;
    margin-top: 10px;
    text-align: center;
    font-size: 12px;
    color: var(--sf-ink-3, #9a8f83);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.sf-cf-dispute:hover { color: #a03030; }

/* ── SHARE ────────────────────────────────────────────────────────────
   Quiet by default. Forwarding is the highest-value thing that happens on
   this page, but a loud share button on every card would shout over the
   thing being shared. It gets loud on hover, and it never competes with the
   price. */
/* BOTH service layouts. There are two — the plan card (sf-plan-wrap) and the
   compact card (sf-svc) — and a share button on only one of them is a share
   button most professionals will never see, because the service worth
   forwarding is usually the one with plans. */
.sf-svc, .sf-plan-wrap { position: relative; }
.sf-svc-share {
    position: absolute;
    top: 8px; right: 8px;
    z-index: 3;
    width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
    background: rgba(255,255,255,.86);
    border: 1px solid var(--sf-line);
    color: var(--sf-ink-3, #9a8f83);
    cursor: pointer;
    transition: color .14s ease, background .14s ease, transform .12s ease;
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}
.sf-svc-share:hover {
    color: #fff;
    background: #25D366;            /* WhatsApp — where it is actually going */
    border-color: #1eb455;
    transform: translateY(-1px);
}

/* ADDITIVE ONLY. The share button must not change the box it sits in.
   An inline SVG has its own line-box, and dropping one into .sf-share-inline
   shifted the row's baseline — so the URL beside it LOOKED like it had changed
   font. Nothing about the box's typography moved; the button was pushing it
   around. vertical-align + a fixed box take it out of the text flow entirely. */
.sf-copy-share {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    /* CD-69 — a real touch target, not a 22px sliver. */
    width: 40px;
    height: 40px;
    padding: 0;
    margin-left: 4px;
    line-height: 1;
}
.sf-copy-share svg { display: block; width: 18px; height: 18px; }
.sf-copy-share:hover { background: #25D366; color: #fff; border-color: #1eb455; }

.sf-vw-acts { display: flex; align-items: center; gap: 6px; }
.sf-vw-share {
    width: 30px; height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 9px;
    background: transparent;
    border: 1px solid var(--sf-line);
    color: var(--sf-ink-2, #6b6058);
    cursor: pointer;
    transition: color .14s ease, background .14s ease;
}
.sf-vw-share:hover { color: #fff; background: #25D366; border-color: #1eb455; }

/* The forwarded link landed. Say WHICH one — she arrives mid-page and would
   otherwise have to guess which of six services the link was about. */
.sf-svc.is-focused,
.sf-plan-wrap.is-focused {
    box-shadow: 0 0 0 2px var(--sf-accent);
    border-radius: 14px;
    transition: box-shadow .3s ease;
}

/* ── TOAST ────────────────────────────────────────────────────────────
   Bottom-centre on mobile (thumb country, above the fold, never under the
   drawer), bottom-left on desktop. Dark, brief, unmissable, and it does not
   block anything. It exists because a silent add reads as a broken button. */
.sf-toast {
    position: fixed;
    left: 50%;
    bottom: 26px;
    transform: translate(-50%, 14px);
    z-index: 9999;
    background: var(--sf-deep, #2a2521);
    color: #fff;
    font-family: var(--sf-body);
    font-size: 13.5px;
    font-weight: 600;
    padding: 11px 18px;
    border-radius: 999px;
    box-shadow: 0 6px 22px rgba(0,0,0,.22);
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
    max-width: calc(100vw - 32px);
    text-align: center;
}
.sf-toast.on { opacity: 1; transform: translate(-50%, 0); }

@media (min-width: 900px) {
    .sf-toast { left: 26px; transform: translate(0, 14px); }
    .sf-toast.on { transform: translate(0, 0); }
}

/* ── THE INLINE ZONE WARNING ──────────────────────────────────────────
   Appears the instant she picks a city we cannot reach, right under the city
   field, while the payment rails below it are hidden. Amber, not red: she has
   not done anything wrong, she just lives somewhere we have not got to. */
.sf-co-zone {
    background: #fff8e6;
    border: 1px solid #f0d69a;
    border-left: 3px solid #d99b1c;
    border-radius: 9px;
    padding: 10px 12px;
    margin: 4px 0 12px;
    font-size: 12.5px;
    line-height: 1.5;
    color: #6b4d0c;
}
.sf-co-zone strong { display: block; font-size: 13.5px; margin-bottom: 1px; }

/* Working, not hung. See the submit handler. */
.sf-dw-go.is-busy {
    opacity: .75;
    cursor: progress;
    position: relative;
    padding-left: 34px;
}
.sf-dw-go.is-busy::before {
    content: '';
    position: absolute;
    left: 14px; top: 50%;
    width: 14px; height: 14px;
    margin-top: -7px;
    border: 2px solid rgba(255,255,255,.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: sf-spin .7s linear infinite;
}
@keyframes sf-spin { to { transform: rotate(360deg); } }

/* ── OUT OF ZONE ──────────────────────────────────────────────────────
   Deliberately NOT styled as an error. She did nothing wrong — she just
   lives somewhere we have not reached yet. Red here would read as "you
   made a mistake," which is both false and the fastest way to lose her.
   Warm, calm, and it points somewhere.                                   */
.sf-oz {
    background: var(--sf-soft, #faf7f3);
    border: 1px solid var(--sf-line, #e6ded4);
    border-radius: 14px;
    padding: 20px 18px;
    margin-bottom: 16px;
    text-align: center;
}
.sf-oz-ic { color: var(--sf-accent, #b07a4a); margin-bottom: 8px; }
.sf-oz-t {
    font-family: var(--sf-serif, Georgia, serif);
    font-size: 19px;
    line-height: 1.3;
    color: var(--sf-ink, #2a2521);
    margin-bottom: 7px;
}
.sf-oz-s { font-size: 13.5px; line-height: 1.55; color: var(--sf-ink-2, #6b6058); }
.sf-oz-cities {
    margin-top: 12px;
    padding: 9px 12px;
    background: #fff;
    border: 1px solid var(--sf-line, #e6ded4);
    border-radius: 9px;
    font-size: 12.5px;
}
.sf-oz-cities .lbl { display: block; color: var(--sf-ink-3, #9a8f83); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 2px; }
.sf-oz-cities .val { color: var(--sf-ink, #2a2521); font-weight: 600; }
/* Her cart is kept. Say so — silence reads as "it's gone." */
.sf-oz-kept { margin-top: 11px; font-size: 12.5px; color: var(--sf-ink-2, #6b6058); }
.sf-oz-ok {
    margin-top: 11px;
    padding: 8px 12px;
    background: #f0f7f2;
    border: 1px solid #cfe4d6;
    border-radius: 9px;
    font-size: 12.5px;
    color: #1a7a50;
}
.sf-oz-acts { margin-top: 15px; display: flex; flex-direction: column; gap: 8px; }
.sf-oz-acts .sf-dw-go { text-decoration: none; display: block; text-align: center; }

.sf-oz-check {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 12px;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--sf-ink-2, #6b6058);
    cursor: pointer;
}
.sf-oz-check input { margin-top: 2px; flex-shrink: 0; }

/* Segmented payment toggle — exactly two, selected side filled. */
.sf-seg { display: flex; gap: 8px; }
.sf-seg-o { flex: 1; position: relative; cursor: pointer; }
.sf-seg-o input { position: absolute; opacity: 0; pointer-events: none; }
.sf-seg-o span {
    display: flex; align-items: center; justify-content: center; padding: 12px;
    border: 1.5px solid var(--sf-line); border-radius: 11px; background: #fff;
    font-weight: 600; font-size: 13px; color: var(--sf-deep);
}
.sf-seg-o input:checked + span { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }

/* Preorder: one rail, stated rather than chosen. Rendered in the selected
   style because it IS the selection — a greyed-out control would read as
   something she failed to pick. */
/* ── Drawer confirmation: shipping + receipt ──────────────────────────────
   Same information the full-page Cart/OrderConfirmation shows, sized for the
   drawer. Quiet by design — the tick, the title and the total are the things
   she should read first; this is what she comes back to re-read. */
.sf-co-ship {
    margin-top: 16px; padding: 14px; border-radius: 12px;
    background: var(--sf-soft); border: 1px solid var(--sf-line); text-align: left;
}
.sf-co-ship-h {
    font-family: var(--sf-mono); font-size: 10.5px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase; color: var(--sf-muted);
    margin-bottom: 10px;
}
.sf-co-ship-r { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
.sf-co-ship-r:last-child { margin-bottom: 0; }
.sf-co-ship-r .k {
    flex: 0 0 82px; font-family: var(--sf-mono); font-size: 10px; font-weight: 600;
    letter-spacing: .07em; text-transform: uppercase; color: var(--sf-muted);
    padding-top: 2px;
}
.sf-co-ship-r .v { flex: 1; font-size: 13px; line-height: 1.45; color: var(--sf-ink); }

.sf-co-receipt {
    margin-top: 12px; padding: 12px 14px; border-radius: 12px;
    background: #edf7f1; border: 1px solid #bfe0cd; text-align: left;
}
.sf-co-receipt-t { font-size: 13px; font-weight: 700; color: #1a7a50; margin-bottom: 3px; }
.sf-co-receipt-b { font-size: 12.5px; line-height: 1.5; color: #2c6047; margin: 0; }

.sf-seg--single .sf-seg-o--fixed {
    display: block; flex: 1; text-align: center; padding: 11px 14px;
    border-radius: 10px; font-size: 14px; font-weight: 600;
    background: var(--sf-deep); color: #fff; border: 1px solid var(--sf-deep);
}

/* Rail chooser pills — which Maquillarte account to pay into (Bancolombia /
   Nequi / Daviplata). Shown only when more than one rail is configured. */
.sf-co-rails { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.sf-co-rail {
    padding: 7px 14px; border-radius: 999px; cursor: pointer;
    border: 1.5px solid var(--sf-line); background: #fff;
    font-family: var(--sf-body); font-weight: 600; font-size: 12.5px; color: var(--sf-deep);
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.sf-co-rail:hover { border-color: var(--sf-accent); }
.sf-co-rail.is-on { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }

/* Delivery ⇄ Pickup toggle — pill segmented control. Pickup active reads GREEN:
   it is the free option (no domicilio), and green signals that plainly. */
.sf-ff { display: flex; gap: 5px; margin: 2px 0 12px; background: var(--sf-soft); border-radius: 999px; padding: 4px; }
.sf-ff-o { flex: 1; position: relative; cursor: pointer; }
.sf-ff-o input { position: absolute; opacity: 0; pointer-events: none; }
.sf-ff-o span {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    padding: 9px 8px; border-radius: 999px; font-weight: 600; font-size: 12.5px;
    color: var(--sf-muted); transition: background .14s ease, color .14s ease;
}
.sf-ff-o input:checked + span { background: #fff; color: var(--sf-deep); box-shadow: 0 1px 4px rgba(0,0,0,.14); }
.sf-ff-o input[value="Pickup"]:checked + span { background: #1a7a50; color: #fff; box-shadow: 0 1px 6px rgba(26,122,80,.35); }

/* Pickup store card — where she collects (🏪 Maquillarte · Santa Marta). */
.sf-co-pickup { margin: 0 0 12px; padding: 12px 13px; border-radius: 11px; background: var(--sf-soft); border: 1px solid var(--sf-line); }
.sf-co-pickup-t { font-weight: 700; font-size: 14px; color: var(--sf-ink); }
.sf-co-pickup-s { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-muted); margin-top: 4px; }

/* The account number is about to be pasted into a bank app. Make it copyable
   and impossible to misread. */
.sf-co-bank { margin-top: 12px; padding: 13px; border-radius: 11px; background: var(--sf-soft); border: 1px dashed var(--sf-accent); }
.sf-co-bank .bk { font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-muted); }
.sf-co-bank .no { font-family: var(--sf-mono); font-size: 20px; font-weight: 600; color: var(--sf-ink); margin-top: 4px; letter-spacing: .02em; word-break: break-all; }
.sf-co-bank .hd { font-size: 12px; color: var(--sf-muted); margin-top: 2px; }
.sf-co-copy {
    margin-top: 9px; padding: 7px 14px; border-radius: 8px; cursor: pointer;
    background: var(--sf-deep); color: #fff; border: none;
    font-family: var(--sf-body); font-weight: 600; font-size: 12px;
}

/* Confirmation — for a guest this screen IS the receipt. */
.sf-co-done { max-width: 520px; }
.sf-co-tick {
    width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    background: var(--sf-soft); color: var(--sf-deep); font-size: 26px; margin-bottom: 6px;
}
.sf-co-lead { font-size: 14px; line-height: 1.6; color: var(--sf-ink); margin: 0 0 14px; }
.sf-co-ref { display: flex; justify-content: space-between; align-items: baseline; padding: 11px 0; border-top: 1px solid var(--sf-line); border-bottom: 1px solid var(--sf-line); }
.sf-co-ref .k { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .07em; text-transform: uppercase; color: var(--sf-muted); }
.sf-co-ref .v { font-family: var(--sf-mono); font-size: 16px; font-weight: 600; color: var(--sf-ink); }
.sf-co-next { margin-top: 14px; font-size: 13.5px; line-height: 1.6; color: var(--sf-ink); }

@media (max-width: 780px) {
    .sf-co-grid { grid-template-columns: 1fr; }
}

/* ══ MEDIA SIZES — HER WORK IS THE PRODUCT ════════════════════
   The proof tiles, the Aura cards and the product chips were sized like
   thumbnails in a list. A bride buys the RESULT: if she cannot see the
   before/after from arm’s length on a phone, the most persuasive thing on
   the page is decoration. Everything below is bigger, on purpose.
   These override the earlier declarations — later rule wins. */
.sf-media-tile { width: 112px; height: 142px; border-radius: 11px; }
.sf-media-tile.sm { width: 96px; height: 122px; }
.sf-media-tile .ml { font-size: 8.5px; padding: 3px 7px; }
.sf-media-tile.video .vp { font-size: 1.6rem; }
.sf-media-strip { gap: 10px; }

/* Aura cards: a vertical video deserves a vertical card you can actually see. */
.sf-vcard { flex: 0 0 168px; border-radius: 14px; }
.sf-vcard .vt { font-size: 12px; }

/* Product chips inside a service — a real swatch, not a dot. */
.sf-svc-prod-chip { font-size: 12px; padding: 4px 12px 4px 4px; gap: 7px; }
.sf-svc-prod-chip img, .sf-svc-prod-chip .ph { width: 28px; height: 28px; }

@media (max-width: 520px) {
    .sf-media-tile { width: 96px; height: 122px; }
    .sf-media-tile.sm { width: 84px; height: 108px; }
    .sf-vcard { flex: 0 0 146px; }
}

/* Checkout inside the drawer: section headers + a scrollable form. */
.sf-co-sec {
    font-family: var(--sf-mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--sf-accent); margin: 18px 0 4px; padding-top: 12px; border-top: 1px solid var(--sf-line);
}
.sf-co-sec:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.js-co-step .sf-lo-i { background: #fff; }

/* ══ RESERVAR + BOOKING PANEL ═════════════════════════════════ */
.sf-bk-f { margin-top: 12px; }
.sf-bk-btn {
    width: 100%; padding: 13px; border-radius: 12px; cursor: pointer;
    background: var(--sf-deep); color: #fff; border: 1px solid var(--sf-deep);
    font-family: var(--sf-body); font-weight: 600; font-size: 14px;
    transition: filter .15s ease, transform .12s ease;
}
.sf-bk-btn:hover { filter: brightness(1.1); transform: translateY(-1px); }

.sf-bk-recap { background: #fff; border: 1px solid var(--sf-line); border-radius: 12px; padding: 13px; position: relative; }
/* Remove the SERVICE, distinct from closing the window. */
.sf-bk-x {
    position: absolute; top: 8px; right: 8px;
    width: 24px; height: 24px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 7px;
    border: 1px solid var(--sf-line);
    background: #fff;
    color: var(--sf-ink-3, #9a8f83);
    cursor: pointer;
    padding: 0;
    transition: color .14s ease, border-color .14s ease, background .14s ease;
}
.sf-bk-x:hover { color: #a03030; border-color: #e6c9c9; background: #fdf5f5; }
/* The service name must not run under the X. */
.sf-bk-recap .sf-bk-svc { padding-right: 30px; }
.sf-bk-svc { font-family: var(--sf-disp); font-size: 16px; font-weight: 700; color: var(--sf-deep); margin-bottom: 8px; }
.sf-bk-recap .r { display: flex; justify-content: space-between; font-size: 13px; padding: 3px 0; color: var(--sf-ink); }
.sf-bk-recap .r span:last-child { font-family: var(--sf-mono); }
.sf-bk-recap .r.total { margin-top: 8px; padding-top: 9px; border-top: 1px dashed var(--sf-line); font-weight: 700; color: var(--sf-deep); font-size: 15px; }

/* Her published availability. When she has none, we ask in words instead of
   faking a calendar she never filled in. */
.sf-bk-slots { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.sf-bk-slot { position: relative; cursor: pointer; }
.sf-bk-slot input { position: absolute; opacity: 0; pointer-events: none; }
.sf-bk-slot span {
    display: block; text-align: center; padding: 9px 6px; border-radius: 9px;
    border: 1px solid var(--sf-line); background: #fff;
    font-family: var(--sf-mono); font-size: 11px; color: var(--sf-ink);
}
.sf-bk-slot input:checked + span { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }

/* The abono — the number that actually reserves the appointment. */
.sf-bk-abono { background: var(--sf-soft); border-radius: 11px; padding: 12px 13px; }
.sf-bk-abono .a, .sf-bk-abono .b { display: flex; justify-content: space-between; align-items: baseline; }
.sf-bk-abono .b { margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--sf-line); opacity: .8; }
.sf-bk-abono .k { font-size: 12px; color: var(--sf-ink); }
.sf-bk-abono .a .v { font-family: var(--sf-mono); font-size: 19px; font-weight: 600; color: var(--sf-deep); }
.sf-bk-abono .b .v { font-family: var(--sf-mono); font-size: 13px; color: var(--sf-muted); }

/* ══ UPLOAD — the proof their money moved ══════════════════════
   A bare <input type=file> is an OS button and an unreadable filename, on
   the one control that proves the transfer happened. This is a drop-zone
   that names what it wants and then SHOWS the screenshot back. */
.sf-up {
    display: block; margin-top: 10px; cursor: pointer; position: relative;
    border: 1.5px dashed var(--sf-accent); border-radius: 12px;
    background: color-mix(in srgb, var(--sf-accent) 6%, #fff);
    padding: 16px; text-align: center;
    transition: background .15s ease, border-color .15s ease;
}
.sf-up:hover { background: color-mix(in srgb, var(--sf-accent) 12%, #fff); }
.sf-up.has { border-style: solid; border-color: var(--sf-line); background: #fff; padding: 10px; text-align: left; }
.sf-up input[type=file] { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }
.sf-up-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; pointer-events: none; }
.sf-up-ic { color: var(--sf-accent); display: flex; }
.sf-up-t { font-weight: 600; font-size: 13px; color: var(--sf-deep); }
.sf-up-s { font-family: var(--sf-mono); font-size: 9px; color: var(--sf-muted); }

/* The preview. They must be able to SEE they picked the right screenshot. */
.sf-up-has { display: flex; gap: 11px; align-items: center; pointer-events: none; }
.sf-up-has img {
    width: 72px; height: 92px; object-fit: cover; border-radius: 8px;
    border: 1px solid var(--sf-line); background: var(--sf-soft);
}
.sf-up-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.sf-up-meta .js-up-name { font-family: var(--sf-mono); font-size: 10px; color: var(--sf-muted); word-break: break-all; }
.sf-up-x {
    pointer-events: auto; cursor: pointer; z-index: 2; position: relative;
    padding: 5px 11px; border-radius: 7px; font-size: 11px; font-weight: 600;
    background: var(--sf-soft); color: var(--sf-deep); border: 1px solid var(--sf-line);
}

/* ══ DAY → TIME ═══════════════════════════════════════════════ */
.sf-bk-days { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.sf-bk-days::-webkit-scrollbar { display: none; }
.sf-bk-day {
    flex: 0 0 auto; cursor: pointer; padding: 9px 13px; border-radius: 10px;
    background: #fff; color: var(--sf-deep); border: 1px solid var(--sf-line);
    font-family: var(--sf-mono); font-size: 11px; white-space: nowrap; text-transform: capitalize;
}
.sf-bk-day.on { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }
.sf-bk-times { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin-top: 9px; }

/* ══ DATE → TIME (mockup shape) ═══════════════════════════════ */
.sf-bk-week { display: flex; gap: 7px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.sf-bk-week::-webkit-scrollbar { display: none; }
.sf-bk-dc {
    flex: 0 0 auto; width: 58px; padding: 9px 0; cursor: pointer;
    border: 1.5px solid var(--sf-line); border-radius: 11px; background: #fff; text-align: center;
}
.sf-bk-dc .dn { display: block; font-family: var(--sf-mono); font-size: 9px; text-transform: uppercase; color: var(--sf-muted); }
.sf-bk-dc .dd { display: block; font-family: var(--sf-disp); font-weight: 700; font-size: 18px; color: var(--sf-ink); margin-top: 2px; }
.sf-bk-dc.on { border-color: var(--sf-accent); background: color-mix(in srgb, var(--sf-accent) 9%, #fff); }
.sf-bk-dc.on .dd { color: var(--sf-accent); }
.sf-bk-picked { font-family: var(--sf-mono); font-size: 10px; color: var(--sf-muted); margin-top: 10px; }
.sf-bk-picked b { color: var(--sf-deep); }

/* ══ HER PAYOUT RAILS ═════════════════════════════════════════
   The money goes to HER. All her rails are listed — the customer pays from
   whichever app they actually have. */
.sf-bk-rails-k { font-family: var(--sf-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-muted); margin: 12px 0 7px; }
.sf-bk-rail {
    display: flex; align-items: center; gap: 10px; cursor: pointer;
    border: 1.5px solid var(--sf-line); border-radius: 11px; padding: 11px 12px; margin-bottom: 8px; background: #fff;
}
.sf-bk-rail input { position: absolute; opacity: 0; pointer-events: none; }
.sf-bk-rail:has(input:checked) { border-color: var(--sf-deep); background: var(--sf-soft); }
.sf-bk-rail .rb { flex: 1; min-width: 0; }
.sf-bk-rail .rk { display: block; font-size: 12.5px; font-weight: 600; color: var(--sf-ink); }
.sf-bk-rail .rk .pf { font-family: var(--sf-mono); font-size: 8px; color: var(--sf-accent); margin-left: 6px; }
.sf-bk-rail .rn { display: block; font-family: var(--sf-mono); font-size: 13px; color: var(--sf-deep); margin-top: 2px; word-break: break-all; }
.sf-bk-rail .rh { display: block; font-size: 11px; color: var(--sf-muted); margin-top: 1px; }

/* ══════════════════════════════════════════════════════════════
   THEME PREVIEW + PALETTE GALLERY (admin)

   🔴 THESE USE THE SAME [data-theme] VARIABLES THE REAL STOREFRONT USES.
   The colours are NOT duplicated into C# or into the admin page: a preview
   element simply carries data-theme="noir" and inherits --sf-deep/--sf-accent
   from the palette blocks at the top of this file. If the picker and the page
   ever disagreed, she would choose one thing and get another — so there is
   exactly one definition of what "Noir" means, and it is here.
   ══════════════════════════════════════════════════════════════ */
.sfp {
    border: 1px solid var(--sf-line); border-radius: 14px; overflow: hidden;
    background: var(--sf-bg); font-family: var(--sf-body);
    transition: background .2s ease, border-color .2s ease;
}
.sfp-hero {
    display: flex; align-items: center; gap: 11px; padding: 14px 15px;
    background: linear-gradient(135deg, var(--sf-soft), var(--sf-bg));
    border-bottom: 1px solid var(--sf-line);
}
.sfp-av {
    width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto;
    background: linear-gradient(135deg, var(--sf-deep), var(--sf-accent));
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-family: var(--sf-disp); font-weight: 700; font-size: 19px;
    border: 2px solid #fff;
}
.sfp-name { font-family: var(--sf-disp); font-weight: 700; font-size: 17px; color: var(--sf-deep); line-height: 1.1; }
.sfp-sub { font-family: var(--sf-mono); font-size: 8.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--sf-accent); margin-top: 3px; }
.sfp-body { padding: 13px 15px 15px; }
.sfp-nav { display: flex; gap: 6px; margin-bottom: 12px; }
.sfp-nav i {
    font-style: normal; font-size: 10.5px; font-weight: 600; padding: 5px 10px; border-radius: 14px;
    background: #fff; color: var(--sf-deep); border: 1px solid var(--sf-line);
}
.sfp-nav i.on { background: var(--sf-deep); color: #fff; border-color: var(--sf-deep); }
.sfp-card {
    background: #fff; border: 1px solid var(--sf-line); border-radius: 11px;
    padding: 11px; display: flex; align-items: center; gap: 10px;
}
.sfp-thumb { width: 40px; height: 50px; border-radius: 8px; flex: 0 0 auto; background: linear-gradient(160deg, var(--sf-deep), var(--sf-accent)); opacity: .9; }
.sfp-svc { font-family: var(--sf-disp); font-weight: 700; font-size: 14px; color: var(--sf-ink); }
.sfp-chip { display: inline-block; font-family: var(--sf-mono); font-size: 8.5px; color: var(--sf-deep); background: var(--sf-soft); padding: 3px 7px; border-radius: 6px; margin-top: 4px; }
.sfp-price { font-family: var(--sf-mono); font-size: 13px; color: var(--sf-ink); margin-left: auto; white-space: nowrap; }
.sfp-btn {
    width: 100%; margin-top: 11px; padding: 10px; border-radius: 10px; border: none;
    background: var(--sf-accent); color: #fff; font-family: var(--sf-body); font-weight: 600; font-size: 12.5px;
}
.sfp-foot { font-family: var(--sf-mono); font-size: 8px; letter-spacing: .05em; color: var(--sf-muted); margin-top: 10px; text-align: center; }

/* Gallery — every palette as a mini storefront, so she SEES each one. */
.sfp-gal { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
.sfp-gal .sfp { border-radius: 12px; }
.sfp-gal .sfp-hero { padding: 11px 12px; }
.sfp-gal .sfp-av { width: 34px; height: 34px; font-size: 15px; }
.sfp-gal .sfp-name { font-size: 14px; }
.sfp-gal .sfp-body { padding: 10px 12px 12px; }
.sfp-cap { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 12px; border-top: 1px solid var(--sf-line); background: #fff; }
.sfp-cap .gn { font-weight: 600; font-size: 12px; color: var(--sf-ink); }
.sfp-cap .gt { font-family: var(--sf-mono); font-size: 8px; color: var(--sf-muted); margin-top: 1px; }
.sfp-cap .hex { display: flex; gap: 3px; flex: 0 0 auto; }
.sfp-cap .hex b { width: 12px; height: 12px; border-radius: 3px; display: block; }

/* ══════════════════════════════════════════════════════════════
   HERO LAYOUT — CHOSEN BY THE COUNT.

   She picks WHICH photos and IN WHAT ORDER; the page decides the shape, so
   the hero cannot come out lopsided regardless of how many she uploads.

     1 → one full-bleed image
     2 → split down the middle
     3 → one tall on the left, two stacked on the right   (slot 1 is the tall)
     4 → a 2×2 grid
     5 → the 3-up composition with two more in the second column

   Desktop only. On mobile the hero stays the slim scrolling strip defined
   above — a stacked wall of photos would push her prices below the fold on
   the one device her whole audience actually uses.
   ══════════════════════════════════════════════════════════════ */
@media (min-width: 900px) {
    .sf-hero-r {
        /* CD-126 — overflow was VISIBLE, so the media images spilled below the
           band and slid under the sticky tab/share strip (the "cut-off images").
           Clip to a fixed-height band; align-self:start keeps the identity column
           free to define the hero height (CD-124), so text is never clipped while
           images never overflow. One clean baseline. */
        display: grid; gap: 3px; padding: 3px; overflow: hidden;
        grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr;
        height: 300px; align-self: start;
    }
    .sf-hero-r .sf-tile { width: auto; height: auto; border-radius: 0; }

    /* 1 — one photo, full bleed. */
    .sf-hero-r.n1 { grid-template-columns: 1fr; }

    /* 2 — split, ONE equal row. CD-125: the general .sf-tile:first-child spans
       two rows (for the n3/n5 tall-first layouts); left uncancelled it made the
       left image tall and the right short — a ragged bottom edge. Cancel it here
       so both images are one height, one baseline. */
    .sf-hero-r.n2 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; }
    .sf-hero-r.n2 .sf-tile:first-child,
    .sf-hero-r.n4 .sf-tile:first-child { grid-row: auto; aspect-ratio: 1; }

    /* 3 — the first photo is TALL. The order she chose is the emphasis. */
    .sf-hero-r.n3 { grid-template-rows: 1fr 1fr; }
    .sf-hero-r.n3 .sf-tile:first-child { grid-row: span 2; }

    /* 4 — an even grid. */
    .sf-hero-r.n4 { grid-template-rows: 1fr 1fr; }

    /* 5 — tall first, four stacked beside it. */
    .sf-hero-r.n5 { grid-template-columns: 1.25fr 1fr 1fr; grid-template-rows: 1fr 1fr; }
    .sf-hero-r.n5 .sf-tile:first-child { grid-row: span 2; }
}

/* The BOOK pill is a form-button now — strip the UA chrome so it still reads
   as a pill sitting on the video. */
form.js-aura-book { margin: 0; display: inline-flex; }
button.sf-vpill { border: none; cursor: pointer; font-family: var(--sf-mono); }

/* ── RICH TEXT (sanitized) — service Description + About-you ─────────
   The whitelist is p / br / b / strong / i / em / u / ul / ol / li /
   h3 / h4, so these are the only shapes it can ever produce. */
.sf-rich > :first-child { margin-top: 0; }
.sf-rich > :last-child { margin-bottom: 0; }
.sf-rich p { margin: .35em 0; }
.sf-rich ul, .sf-rich ol { margin: .4em 0; padding-left: 1.35em; }
.sf-rich li { margin: .15em 0; }
.sf-rich h3, .sf-rich h4 { margin: .5em 0 .25em; font-weight: 700; line-height: 1.3; }
.sf-rich h3 { font-size: 1.02em; }
.sf-rich h4 { font-size: .96em; }
/* About-you was an italic pull-quote; as rich text it reads as normal copy. */
.sf-voice-rich { font-style: normal; }
.sf-voice-rich > :first-child { margin-top: 0; }
.sf-voice-rich > :last-child { margin-bottom: 0; }

/* ── USA DROPS NEEDS AN ACCOUNT ──────────────────────────────────────────────
   Shown in the drawer in place of the guest checkout form. Reads as an
   explanation, not a rejection: she has not done anything wrong, and the
   thing she picked is still hers. */
.sf-pre-acct { padding: 26px 20px 8px; text-align: center; }
.sf-pre-acct-badge {
    display: inline-block; font-family: var(--sf-mono);
    font-size: 9px; font-weight: 700; letter-spacing: .1em;
    color: #fff; background: #12304c; padding: 4px 9px; border-radius: 5px;
    margin-bottom: 14px;
}
.sf-pre-acct h3 { margin: 0 0 10px; font-size: 18px; color: var(--sf-ink); }
.sf-pre-acct p { margin: 0 0 12px; font-size: 13px; line-height: 1.55; color: var(--sf-muted); }
.sf-pre-acct-items {
    list-style: none; margin: 0 0 14px; padding: 10px 12px; text-align: left;
    background: #f4f7fb; border: 1px solid #d8e3f0; border-radius: 9px;
}
.sf-pre-acct-items li { font-size: 12.5px; font-weight: 600; color: #12304c; padding: 2px 0; }
.sf-pre-acct-keep { font-family: var(--sf-mono); font-size: 10.5px; color: var(--sf-muted); }

/* ── THE BALANCE PANEL ───────────────────────────────────────────────────────
   The second payment on a USA Drop, in the drawer. Reuses .sf-dw-tot and the
   rail/copy/receipt classes from the checkout form; only the wrapper is new. */
.sf-bal { padding: 22px 16px 8px; }
.sf-bal-badge {
    display: inline-block; font-family: var(--sf-mono);
    font-size: 9px; font-weight: 700; letter-spacing: .1em;
    color: #fff; background: #12304c; padding: 4px 9px; border-radius: 5px;
    margin-bottom: 12px;
}
.sf-bal h3 { margin: 0 0 8px; font-size: 18px; color: var(--sf-ink); }
.sf-bal-lede { margin: 0 0 14px; font-size: 13px; line-height: 1.55; color: var(--sf-muted); }
.sf-bal-items {
    list-style: none; margin: 0 0 14px; padding: 10px 12px;
    background: #f4f7fb; border: 1px solid #d8e3f0; border-radius: 9px;
}
.sf-bal-items li { font-size: 12.5px; font-weight: 600; color: #12304c; padding: 2px 0; }
.sf-bal-wait {
    margin-top: 14px; padding: 14px; border-radius: 10px;
    background: #eef6f1; border: 1px solid #cfe6da;
}
.sf-bal-wait b { display: block; font-size: 14px; color: #1f6b53; margin-bottom: 5px; }
.sf-bal-wait p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--sf-muted); }
.sf-bal .sf-co-l { display: block; margin-top: 12px; }

/* ── THE CARD PATH, BENEATH THE TRANSFER ─────────────────────────────────
   Second, and it LOOKS second: a hairline rule, a small caps header and the
   ghost button. Transferencia is how most of this balance gets paid, and the
   order on screen should say so rather than presenting two equal choices and
   making her decide which one the shop prefers. */
.sf-bal-card { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--sf-line); }
.sf-bal-card-h {
    font-family: var(--sf-mono); font-size: 9.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--sf-muted); margin-bottom: 9px;
}
/* It leaves the site, and the note says so before she taps. */
.sf-bal-card-n { margin: 8px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--sf-muted); }

/* Balance CTA sits beside the existing .pay CTA; the waiting state is a chip,
   not a button, because there is nothing left for her to do. */
.sf-act-cta.is-waiting {
    background: #eef6f1; color: #1f6b53; border: 1px solid #cfe6da;
    cursor: default; pointer-events: none;
}

/* Arrival date on the preorder receipt — a fact, set apart from the prose
   above it so the eye can find the date without reading the sentence. */
.sf-co-eta {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
    margin-top: 8px; padding: 8px 10px;
    background: #f4f7fb; border: 1px solid #d8e3f0; border-radius: 8px;
    font-size: 12px; color: #2b4a6b;
}
.sf-co-eta b { font-family: var(--sf-mono); font-size: 12.5px; color: #12304c; }

/* Two-part payment state on an order row. Quiet — it qualifies the total above
   it rather than competing with it. */
.sf-ord-split {
    display: flex; flex-wrap: wrap; gap: 4px 14px;
    margin: 4px 0 2px; font-size: 11px; color: #2b4a6b;
}
.sf-ord-split b { font-family: var(--sf-mono); color: #12304c; }
.sf-ord-split .due b { color: #8a5a1e; }

/* Order marks on the calendar are now interactive — say so on hover/press.
   The booking chips already get this from .chip-booking; the day-list rows
   did not, because until now an order row was a plain div. */
.sf-cal-dl-i.js-order-open, .chip-booking.js-order-open { cursor: pointer; }
.sf-cal-dl-i.js-order-open:hover, .chip-booking.js-order-open:hover { filter: brightness(.96); }
.sf-cal-dl-i.js-order-open:active, .chip-booking.js-order-open:active { transform: scale(.985); }

/* Arriving from a calendar mark: say WHICH order without shouting. A ring and
   a lift, faded in and out, so the eye is led rather than yanked. Removed by
   JS after ~2.6s — a permanent marker would still be pointing at this row the
   next time the drawer opens for something else entirely. */
.sf-ord.is-focus {
    box-shadow: 0 0 0 2px var(--sf-deep), 0 8px 22px rgba(28,26,23,.18);
    border-color: var(--sf-deep);
    transition: box-shadow .28s ease, border-color .28s ease, transform .28s ease;
    transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
    .sf-ord.is-focus { transition: none; transform: none; }
}

/* WhatsApp mark on the Confirm button — WhatsApp green, not the button's text
   colour. It was inheriting currentColor, so it came out white and read as a
   generic icon; the whole point is that she recognises the mark at a glance and
   knows that is how she will be contacted. #25D366 is WhatsApp's own green and
   it holds up on the plum CTA.

   Full opacity for the same reason: a brand mark at 95% reads as disabled. */
.sf-dw-go .sf-co-wa { vertical-align: -2px; margin-right: 6px; color: #25D366; }
