*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

@font-face { font-family: 'Selawik'; font-weight: 300; font-display: swap; src: url("../fonts/selawik/selawkl.2080ecbe44ab.woff2") format('woff2'); }
@font-face { font-family: 'Selawik'; font-weight: 400; font-display: swap; src: url("../fonts/selawik/selawk.c1aa8c51674c.woff2") format('woff2'); }
@font-face { font-family: 'Selawik'; font-weight: 600; font-display: swap; src: url("../fonts/selawik/selawksb.17eab24cc0c2.woff2") format('woff2'); }
@font-face { font-family: 'Selawik'; font-weight: 700; font-display: swap; src: url("../fonts/selawik/selawkb.685fb6280fec.woff2") format('woff2'); }

/* Registered so the heading glint can fade in and out instead of
   popping. An unregistered custom property cannot be transitioned. */
@property --lit { syntax: "<number>"; inherits: false; initial-value: 0; }

:root {
    --red-deep:   #170504;
    --red-velvet: #3c0c0a;
    --red-mid:    #641411;
    --red-warm:   #911d18;
    --silver-dim: #7a7474;
    --silver-mid: #aaaaaa;
    --silver-hi:  #e4e4e4;
    --white:      #f8f8f8;
    --gold:       #c9a84c;
    --gold-hi:    #e8c96a;
    /* ── The pointer ──
       Gold arrow, dark edge; white while over anything that answers.
       The dark stroke is what keeps it on the page over the gold
       buttons and the cream pin cards, where a bare gold arrow
       disappears — see /elfil/lab/cursor/, where that is the whole
       test. The two numbers after the url are the hotspot, the pixel
       that actually points; the keyword after the comma is required,
       and without it the declaration is invalid and the system arrow
       comes back with no warning. Chrome drops any cursor over
       128x128, so these stay small. */
    --cur-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M4 2 4 19 8.6 14.7 11.4 21 14.6 19.6 11.8 13.5 18 13.2Z' fill='%23e8c96a' stroke='%23170504' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E") 4 2, auto;
    --cur-hand: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M4 2 4 19 8.6 14.7 11.4 21 14.6 19.6 11.8 13.5 18 13.2Z' fill='%23ffffff' stroke='%23170504' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E") 4 2, pointer;
    --cur-beam: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='24'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M5 3h6M8 3v18M5 21h6' stroke='%23170504' stroke-width='3.6'/%3E%3Cpath d='M5 3h6M8 3v18M5 21h6' stroke='%23e8c96a' stroke-width='1.5'/%3E%3C/g%3E%3C/svg%3E") 8 12, text;
    --serif: 'Playfair Display', Georgia, serif;
    --sans:  'Selawik', 'Segoe UI', system-ui, sans-serif;
}

/* ── Selection ─────────────────────────────────────────────
   The UA default is a flat system blue — the one colour on screen that
   belongs to no part of this palette. Gold ground, with the same
   near-black ink the gold buttons already wear.

   -webkit-text-fill-color HAS to be restated here. The ore-finished
   headings set it to transparent, and it beats `color` for the glyph
   fill, so without this line a selected heading is an empty gold bar
   with no letters in it.

   ::selection accepts only color, background-color, text-shadow,
   text-decoration and the fill; anything else written here is dropped.
   If you ever add ::-moz-selection, give it its OWN rule — one selector
   list holding both invalidates the lot in a browser that knows only
   one of them. */
::selection {
    background: var(--gold-hi);
    color: #2a0907;
    -webkit-text-fill-color: #2a0907;
    text-shadow: none;
}
/* Gold on gold goes muddy — the same trouble .btn-gold's arrow has, and
   it is the one surface bright enough to swallow the highlight. Invert
   it: dark ground, gold ink. */
.btn-gold::selection {
    background: #2a0907;
    color: var(--gold-hi);
    -webkit-text-fill-color: var(--gold-hi);
}

html { scroll-behavior: smooth; }
body {
    cursor: var(--cur-arrow);
    font-family: var(--serif);
    background-color: var(--red-deep);
    color: var(--silver-hi);
    overflow-x: hidden;
    position: relative;
}
body.intro-lock { overflow: hidden; }

/* Links and controls take the hand. The browser already gives them a
   pointer of its own, but that is the SYSTEM hand, and it looked wrong
   sitting next to a drawn arrow everywhere else — 15 elements on the
   home page alone were still falling back to it. Element selectors, so
   anything with a class of its own still wins. */
a, button, summary, select, label[for], [role="button"] {
    cursor: var(--cur-hand);
}
/* A control that cannot be used should not claim it can. */
button:disabled, [aria-disabled="true"] { cursor: var(--cur-arrow); }

/* ── Over text ──
   A drawn I-beam: gold over a dark halo, so it holds on the velvet and
   on the cream pin cards alike. Two strokes of the same path rather
   than a fill, which is what keeps a 1.5px bar from disappearing.

   It goes where the I-beam already belonged — the fields — and over
   running copy, which is the selectable part. Headings keep the arrow:
   they are one line to look at, not a paragraph to drag through.

   Two exclusions, both found by checking rather than by guessing. The
   .eyebrow is a <p>, so a blanket rule put a text cursor on a
   letter-spaced kicker that carries a diamond glyph; it reads as a
   label, and it keeps the arrow. And copy INSIDE a link or a button
   inherits, so a paragraph in a clickable card still says press me
   rather than select me — the card is the target, not the sentence.

   The hotspot is the centre of the bar, 8 12, which is where a text
   caret is measured from. */
input:not([type="button"]):not([type="submit"]):not([type="checkbox"]):not([type="radio"]),
textarea,
[contenteditable] { cursor: var(--cur-beam); }

p, li, blockquote, dd, figcaption { cursor: var(--cur-beam); }
.eyebrow { cursor: var(--cur-arrow); }
a p, a li, button p, button li, [role="button"] p, [role="button"] li,
a .eyebrow, button .eyebrow { cursor: inherit; }

/* ── Protected artwork ──────────────────────────────────────────────
   Every image and clip on this site is Juan's own drawing, so none of
   them are meant to be dragged off the page or long-pressed into a
   camera roll. This is the same treatment Khora gives its game assets
   (chess/css/piece-effects.css, chess/css/global.css): kill the native
   drag, the selection, and the iOS "Save Image" callout. The right-click
   and dragstart guards in base.js finish the job.

   What it does NOT do: make the files unreachable. The browser still has
   to fetch each one to draw it, so anyone who opens devtools or the
   network tab can still get at them. This stops casual saving, which is
   exactly as far as Khora's own protection goes. */
img, video {
    -webkit-user-drag: none;
    -khtml-user-drag: none;
    -moz-user-drag: none;
    -o-user-drag: none;
    user-drag: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

/* ── Velvet ── */
body::before {
    content: '';
    position: fixed; inset: 0;
    background:
        radial-gradient(ellipse 90% 42% at 50% -6%, rgba(232,186,120,0.16) 0%, transparent 62%),
        radial-gradient(ellipse 10% 150% at 6% 38%,  rgba(145,29,24,0.22) 0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 19% 58%, rgba(23,5,4,0.26)    0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 33% 32%, rgba(145,29,24,0.18) 0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 48% 62%, rgba(23,5,4,0.22)    0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 63% 28%, rgba(145,29,24,0.18) 0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 77% 56%, rgba(23,5,4,0.26)    0%, transparent 80%),
        radial-gradient(ellipse 10% 150% at 91% 36%, rgba(145,29,24,0.16) 0%, transparent 80%),
        radial-gradient(ellipse 95% 85% at 50% 38%, rgba(145,29,24,0.35) 0%, transparent 75%),
        radial-gradient(ellipse at center, transparent 48%, rgba(0,0,0,0.5) 100%);
    pointer-events: none;
    z-index: 0;
}
body::after {
    content: '';
    position: fixed; inset: 0;
    opacity: 0.07;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
    pointer-events: none;
    z-index: 0;
}
/* ── Spines ──
   Juan's thorn branch, used exactly as drawn: its own colours, its own
   shape, no mask and no tint. Not a pattern and not a border — a few
   copies at irregular heights down each edge, mostly pushed off the
   side, so one passes by as you scroll.

   The drawing stands VERTICALLY in the file, so --rot is a tilt away
   from upright. Keep these small: the intent is a spine leaning, never
   one lying flat.

   position: absolute + inset: 0 on a position: relative body spans the
   whole DOCUMENT, so the branches scroll with the content instead of
   hanging in the viewport. overflow: hidden means the overhang adds
   nothing to scrollWidth. z-index 0 sits above the velvet's gradients
   and below the noise grain, <main> (1) and everything over it.

   Nothing animates. */
.spines {
    position: absolute; inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;

    --spine-w: 300px;     /* width before each copy's own --scale */
    --spine-o: 1;         /* baseline, multiplied by each --op    */
    --spine-out: 0.26;    /* share of the width hung off the edge */
}
.spines b {
    position: absolute;
    display: block;
    top: var(--y, 0%);
    width: calc(var(--spine-w) * var(--scale, 1));
    aspect-ratio: 560 / 1233;
    opacity: calc(var(--spine-o) * var(--op, 1));
    background: url("../marks/spine-art.ada81567bc6d.webp") no-repeat center / 100% auto;
    /* --side mirrors the drawing for whichever edge it is on. The branch
       has a handedness — it curves — so the same copy shifted to the right
       reads backwards against that edge. --rot stays literal: the asset is
       built with the ink's own principal axis standing at 90deg (measured,
       not eyeballed — the first cut sat at 59.5deg, which is why every
       branch looked like it was lying down), so mirroring about the
       vertical leaves that axis vertical and --rot is the tilt you see. */
    transform: rotate(var(--rot, 0deg)) scaleX(calc(var(--flip, 1) * var(--side, 1)));
}
/* The right side needs more overhang than the left. Mirroring reflects the
   ink about the box centre and the tall box swings it the other way under
   rotation, so the same --spine-out leaves the right ones floating inboard
   while the left ones sit on their edge. */
.spines b.r { --side: -1; --spine-out: 0.62; }
.spines b.r.corner { --spine-out: 0.74; }
.spines b.l { left:  calc(var(--spine-w) * var(--scale, 1) * var(--spine-out) * -1 + var(--x, 0px)); }
/* The corner pair hangs out further, so the diagonal runs off the edge
   rather than sitting politely inside it. */
/* The corner pair hangs out further, so the diagonal runs off the edge
   rather than sitting politely inside it.

   They are pinned in PIXELS, not with --y. A percentage is a share of the
   document, so the same 98% put the bottom one 19px short of the edge on
   the illustration page (8598px tall) and 91px past it on About (3095px).
   Pixels put them on the corner on every page. */
.spines b.corner { --spine-out: 0.46; }
.spines b.corner-t { top: -42px; }
.spines b.corner-b { top: auto; bottom: -42px; }
.spines b.r { right: calc(var(--spine-w) * var(--scale, 1) * var(--spine-out) * -1 - var(--x, 0px)); }

/* ── The stage light ──
   A followspot, not a background wash: an even pool, a penumbra at the
   rim, a hot centre and a faint haze halo from light scattering in air.
   base.js tracks it with an operator's lag and rides the dimmer up and
   down — see there for the timings.

   z-index 6 puts it OVER the page content so the light falls on the type
   as well as the velvet, which is the whole point. That is safe because
   everything that must stay unwashed sits above it at the body level:
   topbar 50, shop drawer 80/81, illustration lightbox 90, home intro 100,
   contact modal 2000. Anything inside <main> is inside main's own
   stacking context (z-index 1) and is washed regardless of its own
   z-index, which is what we want. */
.spot {
    --pool: 300px;         /* pool radius */
    --pen: 38;             /* penumbra width, % of the radius */
    --i: 0.5;              /* dimmer */
    --haze: 1;             /* atmospheric halo */
    --gel: 255, 214, 160;  /* tungsten */
    --sx: 50vw; --sy: 40vh;

    position: fixed; inset: 0;
    pointer-events: none;
    z-index: 6;
    mix-blend-mode: soft-light;
    opacity: 0;                        /* the dimmer starts out */
    transition: opacity 450ms linear;  /* base.js swaps the duration per direction */
    background:
        radial-gradient(circle calc(var(--pool) * 0.34) at var(--sx) var(--sy),
            rgba(var(--gel), calc(0.10 * var(--i))) 0%,
            rgba(var(--gel), 0) 100%),
        radial-gradient(circle var(--pool) at var(--sx) var(--sy),
            rgba(var(--gel), calc(0.17 * var(--i))) 0%,
            rgba(var(--gel), calc(0.155 * var(--i))) calc(100% - var(--pen) * 1%),
            rgba(var(--gel), calc(0.060 * var(--i))) calc(100% - var(--pen) * 0.42%),
            rgba(var(--gel), 0) 100%),
        radial-gradient(circle calc(var(--pool) * 2.3) at var(--sx) var(--sy),
            rgba(var(--gel), calc(0.05 * var(--i) * var(--haze))) 0%,
            rgba(var(--gel), calc(0.018 * var(--i) * var(--haze))) 46%,
            rgba(var(--gel), 0) 100%);
}
/* No cursor, no lamp. On touch, pointermove fires while scrolling, so
   leaving it on would flash the light down the page on every swipe. */
@media (hover: none) {
    .spot { display: none; }
}
main, header, footer { position: relative; z-index: 1; }

/* ══════════════════════════════════════════════════════════════
   Vein-ore text finish — the name row and every heading.

   Blobs of silver, gold and platinum over a dark matrix, marbled
   like a cut rock face, clipped to the glyphs. On hover base.js
   feeds --mx/--my and lifts --lit, lighting a glint that follows
   the cursor in both axes.

   Three things this depends on, each of which silently breaks it:
   · The `background` shorthand RESETS background-clip, so the clip
     must be declared after it (it is, in this same rule). Never set
     `background` on a heading in a later rule without re-clipping.
   · The ore tiles at a fixed px width, so one blob does not smear
     across a wide heading. Small type overrides --ore-tile.
   · --lit is registered below as a <number> — that is the only
     reason it can transition. Leave --mx/--my unregistered, or they
     interpolate and the glint lags behind the cursor.
   ══════════════════════════════════════════════════════════════ */
.h1, .h2, .headline, .hero-name, .brand-name, .intro-name span {
    --mx: 50%; --my: 50%;
    --ore-tile: 520px;   /* physical grain of the ore */
    --ray-i: 1;          /* glint brightness */
    --ray-w: 1;          /* glint size */
    /* The glint is a long flat streak — roughly 9:1 — which is right for
       a heading and far too wide for a word of small caps, where it just
       washes the lot. --ray-h stretches it vertically so small type can
       have a rounder, more local highlight without shrinking it away. */
    --ray-h: 1;
    --grain: 1;          /* brushed texture */

    /* The ore only paints inside the element's own box, so any glyph
       that pokes out of it simply is not painted. These line-heights
       are tighter than Playfair's natural one, which pushes descenders
       (y, g, p) below the box: at 51px/1.1 the baseline leaves 6.7px of
       room and the ink needs 10px, so the tails were being sliced off.
       The padding buys the paint area back; the negative bottom margin
       (and the calc()s on .h1/.h2 margin-top) keep the layout identical. */
    padding: 0.06em 0 0.12em;
    margin-bottom: -0.12em;

    background:
        /* the glint: a wide flat streak crossed by a tall thin one,
           over a dark halo — white only reads bright next to dark */
        radial-gradient(ellipse calc(150px * var(--ray-w)) calc(17px * var(--ray-w) * var(--ray-h)) at var(--mx) var(--my),
            rgba(255,255,255, calc(1.00 * var(--ray-i) * var(--lit))) 0%, rgba(255,255,255,0) 70%) 0 0 / 100% 100% no-repeat,
        radial-gradient(ellipse calc(14px * var(--ray-w)) calc(95px * var(--ray-w) * var(--ray-h)) at var(--mx) var(--my),
            rgba(255,255,255, calc(0.85 * var(--ray-i) * var(--lit))) 0%, rgba(255,255,255,0) 70%) 0 0 / 100% 100% no-repeat,
        radial-gradient(circle calc(17px * var(--ray-w)) at var(--mx) var(--my),
            rgba(255,255,255, calc(1.00 * var(--ray-i) * var(--lit))) 0%, rgba(255,255,255,0) 82%) 0 0 / 100% 100% no-repeat,
        radial-gradient(ellipse calc(300px * var(--ray-w)) calc(60px * var(--ray-w) * var(--ray-h)) at var(--mx) var(--my),
            rgba(0,0,0,0) 26%,
            rgba(0,0,0, calc(0.30 * var(--ray-i) * var(--lit))) 58%,
            rgba(0,0,0,0) 100%) 0 0 / 100% 100% no-repeat,
        /* the ore */
        repeating-linear-gradient(97deg,
            rgba(255,255,255, calc(0.10 * var(--grain))) 0 1px,
            rgba(0,0,0,       calc(0.10 * var(--grain))) 1px 2.4px) 0 0 / auto repeat,
        radial-gradient(ellipse 34% 120% at 9% 28%,  #eef2f8 0%, rgba(238,242,248,0) 62%) 0 0 / var(--ore-tile) 100% repeat,
        radial-gradient(ellipse 26% 100% at 28% 80%, #8a6520 0%, rgba(138,101,32,0)  58%) 0 0 / var(--ore-tile) 100% repeat,
        radial-gradient(ellipse 30% 130% at 45% 18%, #ffeeb0 0%, rgba(255,238,176,0) 56%) 0 0 / var(--ore-tile) 100% repeat,
        radial-gradient(ellipse 28% 110% at 64% 70%, #ffffff 0%, rgba(255,255,255,0) 60%) 0 0 / var(--ore-tile) 100% repeat,
        radial-gradient(ellipse 32% 120% at 84% 30%, #d4a94f 0%, rgba(212,169,79,0)  60%) 0 0 / var(--ore-tile) 100% repeat,
        radial-gradient(ellipse 30% 110% at 97% 74%, #b6bdc9 0%, rgba(182,189,201,0) 60%) 0 0 / var(--ore-tile) 100% repeat,
        linear-gradient(165deg, #656b77 0%, #434954 48%, #606773 100%) 0 0 / 100% 100% no-repeat;

    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    transition: filter 0.5s ease, --lit 0.28s ease;
}

/* ── The mark under the pointer ──────────────────────────────────────
   Every sigil sits in a .mk host: the host owns the lean and the glow,
   the drawing inside owns nothing but its own size. That split is what
   lets each mark keep the movement it already had — the brand's 45°
   turn, the hero mark's lean into the name you are on — and take the
   pointer tilt on top of it instead of fighting it.

   The glow is the mark's OWN SILHOUETTE, not a disc behind it: three
   drop-shadows of the drawing, each blurrier and fainter than the last.
   Chained shadows compound — every one blurs the result of the one
   before it — which is what turns three hard copies of the bishop into
   a single bloom that follows its line. --mk-glow carries the metal, so
   a silver mark glows silver and a gold one gold.

   This is the drop-shadow the .hero-logo note warns about, and that
   warning still holds — which is why the filter is declared only while
   the mark is lit, and why the radii never change while it is. Chrome
   blurs the silhouette once on the way in and the pointer tilt just
   re-composites the cached result.

   The radii are fractions of --mk-size, so a 22px brand mark and a 64px
   modal mark glow by the same AMOUNT rather than the same pixels. Every
   host sets --mk-size and takes its box from it.

   sigil.js writes --mk-rx / --mk-ry and the two classes. Everything
   above is decided here. */
@property --mk-rx { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --mk-ry { syntax: "<angle>"; inherits: false; initial-value: 0deg; }

/* ── The mark is not a file to be taken ───────────────────────────────
   Every sigil on the site is an <svg> wrapping <use href="#sigil…">, and
   the symbols behind those references wrap an <image>. Chrome treats
   that <image> as a picture, so right-clicking any mark — the brand, the
   hero, the finale, the contact modal, the bubble's token — offered
   "Save image as…" and handed the drawing over.

   pointer-events: none on the wrapper is what removes it from the menu:
   the property is inherited, so it reaches the <image> inside the <use>
   shadow tree, and the hit test then lands on whatever is behind the
   mark instead. Right-clicking the brand still offers the LINK options,
   which is correct — it is a link.

   Selected with :has() rather than by listing cm-sigil, finale-sigil,
   sg, sig and the unclassed one in about.html, so a mark added later is
   covered without anyone remembering to come back here.

   This costs nothing: the tilt and the lighting are driven by pointer
   events on the .mk host or on a named zone (see sigil.js), never on the
   drawing itself.

   What it does NOT do is make the file unreachable — the URL is still in
   the page source, and a screenshot always works. It stops the casual
   right-click and the drag-to-desktop, which is what the menu offered. */
svg:has(> use[href^="#sigil"]) {
    pointer-events: none;
    -webkit-user-drag: none;
            user-drag: none;
    -webkit-user-select: none;
            user-select: none;
}

.mk {
    position: relative;
    display: inline-block;
    line-height: 0;
    width: var(--mk-size); height: var(--mk-size);
    --mk-size: 40px;
    --mk-glow: 232, 201, 106;
    transform: perspective(var(--mk-persp, 320px)) rotateX(var(--mk-rx)) rotateY(var(--mk-ry));
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Tracking the cursor, not chasing it. */
.mk.mk-live { transition: none; }
/* The drawing fills the host, whatever the host's size is. Every place
   that uses a mark also sizes its own svg, but a bare .mk must work on
   its own or the next one added gets the 300x150 default. */
.mk svg { width: 100%; height: 100%; transition: filter 0.35s ease; }

/* Lit by the pointer, or — on the hero mark — by the name it belongs to. */
.mk-lit svg,
.hero-row.state-left  .hero-logo svg,
.hero-row.state-right .hero-logo svg {
    filter:
        brightness(1.1)
        drop-shadow(0 0 calc(var(--mk-size) * 0.05) rgba(var(--mk-glow), 0.55))
        drop-shadow(0 0 calc(var(--mk-size) * 0.13) rgba(var(--mk-glow), 0.42))
        drop-shadow(0 0 calc(var(--mk-size) * 0.28) rgba(var(--mk-glow), 0.30));
}

/* ── Masthead (home) ── */
.mast {
    display: flex; flex-direction: column; align-items: center;
    padding: 30px 40px 0;
    text-align: center;
}
.hero-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    column-gap: clamp(12px, 2.4vw, 26px);
    width: 100%;
    max-width: 1100px;
}
#nameLeft  { justify-self: end; }
#nameRight { justify-self: start; }
.hero-logo { justify-self: center; }

.hero-name {
    font-family: var(--serif);
    font-weight: 600;
    font-size: clamp(0.95rem, 1.9vw, 1.5rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    cursor: var(--cur-arrow);
    user-select: none;
    white-space: nowrap;
    line-height: 1.3;
    /* Small type: tighter ore and a glint scaled to match. */
    --ore-tile: 300px;
    --ray-w: 0.5;
}
.hero-name:hover { filter: drop-shadow(0 0 14px rgba(210,170,60,0.35)); }

.hero-logo {
    position: relative;
    --mk-size: clamp(28px, 3.2vw, 42px);
    --mk-persp: 340px;
    /* The resting shadow is baked into the artwork; nothing but the
       transform moves until the mark is lit. */
    transition: transform 0.65s cubic-bezier(0.34, 1.46, 0.64, 1);
}
/* Four stacked copies: outline silver/gold (os, og) and solid silver/gold
   (fs, fg). All four share one ink bounding box, so they register exactly
   and a crossfade reads as the same mark changing state, not two marks
   swapping.

   The mark rests as an outline and floods solid on hover, taking the metal
   of the name you are on. At rest it keeps the metal of the name you last
   CLICKED — J.M. El-Fil leaves it silver, Juan Martínez gold — so it holds
   the last side chosen instead of always falling back to one.

   data-pick lives on <html>, not on the hero row, because the brand mark
   in the top bar wears the same choice on pages that have no hero row at
   all. base.html sets it before first paint; base.js writes it on a click.
   Scoped to .hero-logo / .brand-mk on purpose — sigil_lab.css drives the
   same four classes off its own [data-finish] modes and must not inherit
   any of this. */
.hero-logo .sg,
.brand-mk  .sg {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0;
    transition: opacity 0.45s ease, filter 0.35s ease;
}
/* Silver until a pick says otherwise, so a blocked localStorage or no JS
   at all still leaves a mark on the page rather than an empty box. */
.hero-logo .sg-os,
.brand-mk  .sg-os { opacity: 1; }
[data-pick="right"] .hero-logo .sg-os,
[data-pick="right"] .brand-mk  .sg-os { opacity: 0; }
[data-pick="right"] .hero-logo .sg-og,
[data-pick="right"] .brand-mk  .sg-og { opacity: 1; }
.hero-row.state-left  .sg-os,
.hero-row.state-left  .sg-og { opacity: 0; }
.hero-row.state-left  .sg-fs { opacity: 1; }
.hero-row.state-right .sg-os,
.hero-row.state-right .sg-og { opacity: 0; }
.hero-row.state-right .sg-fg { opacity: 1; }

/* The lean into the hovered name, with the pointer tilt still riding on
   top of it — hence the .mk vars repeated here rather than a bare
   rotate(), which would wipe them. */
.state-left  .hero-logo { transform: perspective(var(--mk-persp)) rotateX(var(--mk-rx)) rotateY(var(--mk-ry)) rotate(-10deg) scale(1.08); }
.state-right .hero-logo { transform: perspective(var(--mk-persp)) rotateX(var(--mk-rx)) rotateY(var(--mk-ry)) rotate(10deg) scale(1.08); }

/* The glow takes whatever metal the mark is currently wearing: silver
   on the J.M. El-Fil side, gold on the Juan Martínez side. Hovering
   either name lights it too, so the mark answers the name, not just
   the cursor on itself. */
.hero-logo { --mk-glow: 228, 228, 228; }
[data-pick="right"] .hero-logo { --mk-glow: 232, 201, 106; }
.hero-row.state-left  .hero-logo { --mk-glow: 228, 228, 228; }
.hero-row.state-right .hero-logo { --mk-glow: 232, 201, 106; }
/* Clicking a name changes the resting mark, so it should look clickable. */
.hero-name { cursor: var(--cur-hand, pointer); }

/* ── Navigation ── */
.mast-nav {
    display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
    gap: 6px 22px;
    margin-top: 18px;
}
.mast-nav a, .topbar nav a {
    font-family: var(--sans);
    font-size: 0.66rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--silver-mid);
    text-decoration: none;
    position: relative;
    padding: 4px 0;
    transition: color 0.25s ease;
}
.mast-nav a::after, .topbar nav a::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--gold-hi), transparent);
    transform: scaleX(0);
    transition: transform 0.35s ease;
}
.mast-nav a:hover, .topbar nav a:hover, .topbar nav a.on { color: var(--white); }
.mast-nav a:hover::after, .topbar nav a:hover::after, .topbar nav a.on::after { transform: scaleX(1); }
.mast-nav .sep { width: 4px; height: 4px; background: var(--gold); transform: rotate(45deg); opacity: 0.5; }

.topbar {
    position: fixed; top: 0; left: 0; right: 0;
    z-index: 50;
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 32px;
    background: linear-gradient(180deg, rgba(23,5,4,0.92), rgba(23,5,4,0.75));
    backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(233,201,106,0.16);
    transform: translateY(-100%);
    transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.topbar.show { transform: none; }
.topbar .brand {
    display: flex; align-items: center; gap: 10px;
    font-family: var(--serif); font-weight: 600;
    font-size: 0.8rem; letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--silver-hi); text-decoration: none;
}
/* The brand letters take the same vein-ore finish as the names in the
   masthead, with the glint scaled down to match: at 0.8rem the hero's
   ore blobs would each be wider than the whole word, and its glint
   would wash the lot. base.js drives --mx/--my from a hover anywhere on
   the link, not just the letters, so the light and the mark's tilt
   answer the same pointer. */
.brand-name {
    --ore-tile: 170px;
    --ray-w: 0.2;
    --ray-h: 2.4;
}
.topbar .brand:hover .brand-name { filter: drop-shadow(0 0 9px rgba(210,170,60,0.3)); }
/* The mark is 22px — too small to aim at — so the whole brand link is
   its pointer zone (data-sigil-zone in base.html). The 45° turn stays
   on the drawing and the lean on the host, so the two compose. */
.brand-mk { --mk-size: 22px; --mk-persp: 200px; --mk-glow: 228, 228, 228; }
[data-pick="right"] .brand-mk { --mk-glow: 232, 201, 106; }
.topbar .brand svg { width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.34, 1.46, 0.64, 1), opacity 0.45s ease, filter 0.35s ease; }
.topbar .brand:hover svg { transform: rotate(45deg); }
/* The brand does what the hero mark does under a name: rests as an
   outline in the metal you last picked, floods solid while you are on
   it. There is only one name up here, so the hover keeps the resting
   metal instead of choosing a side. */
[data-pick="right"] .brand:hover .sg-og { opacity: 0; }
[data-pick="right"] .brand:hover .sg-fg { opacity: 1; }
.brand:hover .sg-os { opacity: 0; }
.brand:hover .sg-fs { opacity: 1; }
[data-pick="right"] .brand:hover .sg-fs { opacity: 0; }
.topbar nav { display: flex; gap: 24px; }

/* ── Buttons ── */
.cta-row {
    display: flex; flex-wrap: wrap; gap: 14px; justify-content: center;
    margin-top: clamp(18px, 3.5vh, 30px);
}
.btn {
    font-family: var(--sans);
    font-size: 0.68rem; font-weight: 600;
    letter-spacing: 0.2em; text-transform: uppercase;
    text-decoration: none;
    padding: 13px 24px;
    border-radius: 2px;
    cursor: var(--cur-hand, pointer);
    transition: transform 0.25s ease, box-shadow 0.3s ease, background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
    display: inline-flex; align-items: center; gap: 10px;
}
.btn-gold {
    color: #2a0907;
    border: 0;
    background: linear-gradient(135deg, #a57c2a, var(--gold-hi) 45%, #f5e090 55%, var(--gold));
    box-shadow: 0 6px 24px rgba(201,168,76,0.25), inset 0 1px 0 rgba(255,255,255,0.4);
}
.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 10px 34px rgba(233,201,106,0.4), inset 0 1px 0 rgba(255,255,255,0.5); }
.btn-ghost {
    color: var(--silver-hi);
    background: none;
    border: 1px solid rgba(228,228,228,0.25);
}
.btn-ghost:hover { border-color: var(--gold-hi); color: var(--white); background: rgba(233,201,106,0.08); }
.btn .arr { transition: transform 0.25s ease; }
.btn:hover .arr { transform: translateX(4px); }

/* ── The arrow ──────────────────────────────────────────────────────
   Juan's drawn arrow, in place of the typographic one. The drawing
   POINTS RIGHT, so that is 0deg and every other direction is the same
   file turned: the class names the direction and the rotation follows.

   It is the artwork itself, ore and outline intact — not a silhouette.
   The one ground that will not take it is .btn-gold, where gold on gold
   goes muddy; there the SAME drawing is dropped to dark ink with a
   brightness filter, which keeps its texture and matches that button's
   near-black label. Every other arrow in the site sits on something
   dark and wears the gold as drawn.

   The rotation lives on ::before so the carrier's own transform stays
   free: every .go / .cm-go / .btn hover nudge in the sheets keeps
   working untouched, on a span that is no longer a glyph.

   marks/arrow.png -> marks/arrow-art.webp, cropped to a square centred
   on the ink, so a 90deg turn does not walk the arrow off centre and
   the box IS the arrow (no dead margin to size around). */
.arr {
    position: relative;   /* containing block for the shine layer below */
    display: inline-block;
    flex: none;
    width: 1.4em; height: 1.4em;
    vertical-align: -0.34em;
}
.arr::before {
    content: '';
    display: block;
    width: 100%; height: 100%;
    background: url("../marks/arrow-art.c17bd4da879e.webp") no-repeat center / contain;
    transform: rotate(var(--arr-rot, 0deg));
}
.btn-gold .arr::before { filter: brightness(0.26) saturate(1.4); }

/* ── The shine ────────────────────────────────────────────
   The drawing lifts once when you hover the thing it belongs to — the
   whole silhouette at once rather than a light travelling across it.
   Chosen over the travelling sweep in the arrow lab (/elfil/lab/arrow/,
   DEBUG only), which still carries the alternatives.

   It is a THIRD layer: ::before is the drawing and already owns
   --arr-rot, so this lives on ::after, masked to the same artwork so
   the light lands on the arrow's ink instead of flooding its square
   box. The mask takes the SAME rotation as the drawing — without that
   it would be cut to a right-pointing arrow while the arrow you can
   see points down. The fill is flat, so it needs no gradient and no
   travel geometry: a background-color under the mask is the whole of
   it.

   The hover rule must NOT set opacity: 1. The keyframes own opacity
   and end at 0; a normal declaration of 1 would outlive them and leave
   the arrow washed out for as long as the pointer stayed on it. */
.arr::after {
    content: '';
    position: absolute;
    inset: 0;
    transform: rotate(var(--arr-rot, 0deg));
    background: rgba(255, 255, 255, 0.9);
    -webkit-mask: url("../marks/arrow-art.c17bd4da879e.webp") no-repeat center / contain;
            mask: url("../marks/arrow-art.c17bd4da879e.webp") no-repeat center / contain;
    opacity: 0;
    pointer-events: none;
}
/* Every arrow on the site sits inside a link or a button — .btn,
   .cm-opt, .discipline, .next-link, .more a are all one or the other —
   so the interactive element IS the box that contains it. Keying off
   the element rather than naming those five means an arrow dropped
   into a sixth link later gets the shine without touching this rule. */
a:hover .arr::after,
button:hover .arr::after {
    animation: arrFlash 0.5s ease-out;
}
/* Fast up, slow down — a flash decays, it does not fade in and out
   evenly. The lab ran this on a 0.7s cycle whose motion finished at
   65% (an idle tail it needed for loop mode, and which a single hover
   fire does not), so 0.7 × 0.65 ≈ 0.46s is the speed that was judged
   there and 0.5s here is the same gesture. */
@keyframes arrFlash {
    0%   { opacity: 0; }
    25%  { opacity: 1; }
    100% { opacity: 0; }
}

.arr-down { --arr-rot: 90deg; }    /* was &#8595; */
.arr-ne   { --arr-rot: -45deg; }   /* was &#8599; — leaves the site */
.arr-left { --arr-rot: 180deg; }   /* was &#8592; */

/* ── Type & sections ── */
section.block {
    max-width: 1200px;
    margin: 0 auto;
    padding: 110px 40px;
}
.eyebrow {
    font-family: var(--sans);
    font-size: 0.64rem; letter-spacing: 0.34em; text-transform: uppercase;
    color: var(--gold);
    display: flex; align-items: center; gap: 12px;
}
.eyebrow::before { content: ''; width: 5px; height: 5px; background: var(--gold); transform: rotate(45deg); }
.h1, .h2 {
    font-family: var(--serif);
    font-weight: 500;
    color: var(--white);
    text-wrap: balance;
    /* The vein-ore finish itself is shared with .hero-name, above. */
}
.h1:hover, .h2:hover { filter: drop-shadow(0 0 18px rgba(210,170,60,0.32)); }
.h1 { font-size: clamp(2.4rem, 6vw, 5rem); line-height: 1.02; margin-top: calc(18px - 0.06em); }
.h2 { font-size: clamp(1.8rem, 3.8vw, 3.2rem); line-height: 1.1; margin-top: calc(16px - 0.06em); }
.h1 em, .h2 em { font-style: italic; color: var(--gold-hi); -webkit-text-fill-color: var(--gold-hi); }
.lede {
    font-family: var(--sans);
    font-weight: 300;
    font-size: 1.02rem;
    line-height: 1.7;
    color: var(--silver-mid);
    margin-top: 18px;
    max-width: 52ch;
}

/* Instructions worded for the input in use */
.on-touch { display: none; }
@media (hover: none) {
    .on-touch { display: inline; }
    .on-mouse { display: none; }
}

.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.reveal.in { opacity: 1; transform: none; }


/* ── Inner page header, fact strip, next link ── */
.page-head {
    max-width: 1200px;
    margin: 0 auto;
    padding: 150px 40px 40px;
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: 40px 70px;
    align-items: end;
}
.page-head .h1 .sub {
    -webkit-text-fill-color: var(--gold-hi);  /* the heading's clipped fill would swallow it */
    display: block;
    font-size: 0.42em;
    font-style: italic;
    color: var(--gold-hi);
    margin-top: 10px;
    letter-spacing: 0;
}
.page-head .cta-row { justify-content: flex-start; grid-column: 1 / -1; margin-top: 0; }

.facts {
    max-width: 1200px;
    margin: 40px auto 0;
    padding: 26px 40px;
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: 20px;
    border-top: 1px solid rgba(228,228,228,0.08);
    border-bottom: 1px solid rgba(228,228,228,0.08);
}
.fact b {
    display: block;
    font-family: var(--serif); font-weight: 500;
    font-size: clamp(1.6rem, 3vw, 2.4rem);
    color: var(--white);
    line-height: 1;
}
.fact span {
    display: block; margin-top: 8px;
    font-family: var(--sans);
    font-size: 0.58rem; letter-spacing: 0.26em; text-transform: uppercase;
    color: var(--silver-dim);
}

.next-link {
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    max-width: 1200px;
    margin: 0 auto;
    padding: 50px 40px;
    text-decoration: none;
    border-top: 1px solid rgba(228,228,228,0.08);
    border-bottom: 1px solid rgba(228,228,228,0.08);
}
.next-link small {
    font-family: var(--sans);
    font-size: 0.6rem; letter-spacing: 0.3em; text-transform: uppercase;
    color: var(--silver-dim);
}
.next-link strong {
    display: block;
    font-family: var(--serif); font-weight: 500;
    font-size: clamp(2rem, 5vw, 3.6rem);
    color: var(--white);
    margin-top: 6px;
    transition: color 0.3s;
}
.next-link .go { font-size: 2rem; color: var(--gold); transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1); }
.next-link:hover strong { color: var(--gold-hi); }
.next-link:hover .go { transform: translateX(12px); }

@media (max-width: 900px) {
    .page-head { grid-template-columns: 1fr; padding: 110px 20px 20px; }
    .facts { padding: 22px 20px; }
    .next-link { padding: 40px 20px; }
}

/* ── Placeholders for content still to come ── */
.ph {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 10px;
    border: 1px dashed rgba(233,201,106,0.35);
    border-radius: 8px;
    background:
        repeating-linear-gradient(135deg, rgba(233,201,106,0.035) 0 12px, transparent 12px 24px),
        rgba(0,0,0,0.18);
    color: var(--silver-dim);
    text-align: center;
    padding: 18px;
}
.ph svg { width: 34px; height: 34px; opacity: 0.55; stroke: var(--gold); }
.ph span {
    font-family: var(--sans);
    font-size: 0.58rem; font-weight: 600; letter-spacing: 0.26em; text-transform: uppercase;
    color: rgba(233,201,106,0.7);
}
.ph-text {
    font-family: var(--sans);
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--silver-dim);
    border-left: 2px dashed rgba(233,201,106,0.35);
    padding: 6px 0 6px 14px;
    font-style: italic;
}

/* ── Footer ── */
.finale {
    text-align: center;
    padding: 40px 24px 60px;
}
.finale .h2 { font-size: clamp(2rem, 5.2vw, 4.2rem); max-width: 16ch; margin: 18px auto 0; }
.finale .cta-row { margin-top: 36px; }
/* The host carries the size and the centring; the drawing fills it.
   404.html overrides --mk-size on the host for its larger mark. */
.finale-mk {
    display: block;
    margin: 0 auto;
    --mk-size: 46px;
    --mk-persp: 400px;
}
.finale-sigil { display: block; width: 100%; height: 100%; opacity: 0.8; }
.foot {
    margin: 90px auto 0;
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
    max-width: 1200px;
    padding: 22px 16px 0;
    border-top: 1px solid rgba(228,228,228,0.08);
    font-family: var(--sans);
    font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
    color: var(--silver-dim);
}
.foot a { color: inherit; text-decoration: none; }
.foot a:hover { color: var(--gold-hi); }

/* The support ask, on its own line under the footer row. Aligned to the
   copyright above it rather than centred with the rest of .finale: the
   row it sits under is three items spread edge to edge, and a centred
   fourth line reads as off-axis against them, not as the page's close. */
.foot-support {
    max-width: 1200px;
    margin: 14px auto 0;
    padding: 0 16px;
    text-align: left;
    font-family: var(--sans);
    font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
    color: var(--silver-dim);
}
.foot-support a { color: inherit; text-decoration: none; }
.foot-support a:hover { color: var(--gold-hi); }
/* The heart is the only thing here that is not type, so it keeps the
   gold even while the words are dimmed, and warms with them on hover. */
.foot-heart { color: var(--gold-hi); opacity: 0.75; margin-left: 2px; }
.foot-support a:hover .foot-heart { opacity: 1; }

/* Portfolio language switch. Only ever EN / ES, and only ever the
   portfolio — the rest of mywc.io keeps its own language. */
.lang-pick { display: inline-flex; align-items: center; gap: 7px; }
.lang-pick a { transition: color 0.2s; }
.lang-pick a.on { color: var(--gold-hi); }
.lang-pick i { font-style: normal; opacity: 0.35; }

.menu-btn {
    display: none;
    font-family: var(--sans);
    font-size: 0.62rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase;
    color: var(--silver-hi);
    background: none;
    border: 1px solid rgba(228,228,228,0.25);
    padding: 7px 12px;
    cursor: var(--cur-hand, pointer);
}

@media (max-width: 860px) {
    .topbar { padding: 12px 18px; }
    .menu-btn { display: block; }
    .topbar nav { display: none; }
    .topbar nav.open {
        display: flex; flex-direction: column; gap: 0;
        position: absolute; top: 100%; left: 0; right: 0;
        background: rgba(23,5,4,0.97);
        border-bottom: 1px solid rgba(233,201,106,0.16);
        padding: 8px 18px 14px;
    }
    .topbar nav.open a { padding: 12px 0; font-size: 0.72rem; }
    section.block { padding: 80px 20px; }
}
@media (max-width: 600px) {
    /* More air over the masthead, and the names and mark come down a
       size so they stop running at the screen edges. Measured on a
       360px phone: the row was 302px of the 328 available, leaving 26px
       of margin across BOTH sides; at 0.88rem with a 24px mark it is
       280px, so 48px. The tracking is em-based and comes down with the
       type, which is what keeps the small caps sounding the same. */
    .mast { padding: 64px 16px 0; }

    /* The spines are drawn at a FIXED 300px, so the corner one occupies
       the same rectangle whatever the screen: measured x -111..120,
       y -45..186. That is 7% of a desktop and a third of a phone, laid
       straight over the masthead. Smaller, and lifted until it clears
       the padding above the names — it still runs off the corner, it
       just stops competing with the lettering.

       !important because --scale is an inline style in base.html, and
       nothing else beats one. */
    .spines b.corner-t { top: -104px; --scale: 0.22 !important; }
    .hero-name { font-size: 0.95rem; }
    .hero-logo { --mk-size: 28px; }

    /* The row STAYS a row. The masthead IS one name either side of the
       mark; stacking it into three lines is not a smaller version of
       that, it is a different thing. And the space was there all along:
       measured at every phone width, the two names plus the mark and
       its gaps need 302px against 328 available on a 360px phone, and
       more on anything wider. Only below 340px is it genuinely tight,
       and the names shrink there rather than the row breaking up. */
    .hero-row { column-gap: 10px; }

    /* The nav gives up a little SIZE and keeps its tracking. Detracking
       small caps is what takes their voice away, and the em-based
       letter-spacing shrinks with the type anyway. At 0.66rem the four
       labels need 379px and only fit from 414px up; at 0.6rem they need
       341px and fit from 375px. Narrower than that they wrap to two
       centred lines, which is what the flex-wrap here has always been
       for — a nav reads fine on two lines, a split masthead does not. */
    .mast-nav { gap: 6px 12px; }
    .mast-nav a { font-size: 0.6rem; }
    .mast-nav .sep { display: none; }
}
@media (max-width: 340px) {
    /* The narrowest phones, where even 280px leaves only 8px of margin.
       Size only — the tracking stays, so these still read as the same
       lettering rather than a condensed version of it. */
    .hero-name { font-size: 0.88rem; }
}

/* ── Contact modal (opened by any [data-contact] link) ── */
.cm[hidden], .cm-view[hidden] { display: none; }
.cm {
    position: fixed; inset: 0;
    z-index: 2000;
    display: flex; align-items: center; justify-content: center;
    padding: 24px 16px;
    background: rgba(10,3,2,0.78);
    backdrop-filter: blur(8px);
    opacity: 0;
    transition: opacity 0.3s;
}
.cm.open { opacity: 1; }
body.cm-lock { overflow: hidden; }
.cm-card {
    width: min(560px, 100%);
    max-height: calc(100vh - 48px);
    max-height: calc(100dvh - 48px);
    overflow-y: auto;
    padding: 40px 38px 34px;
    border-radius: 16px;
    border: 1px solid rgba(233,201,106,0.28);
    background:
        radial-gradient(ellipse 80% 50% at 50% 0%, rgba(233,201,106,0.12), transparent 70%),
        linear-gradient(180deg, #2a0907, var(--red-deep));
    box-shadow: 0 40px 90px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.06);
    transform: translateY(18px) scale(0.97);
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.cm.open .cm-card { transform: none; }
.cm-foot {
    display: block;
    margin: 26px auto 0;
    padding: 11px 34px;
    border: 1px solid rgba(228,228,228,0.12);
    border-radius: 8px;
    background: rgba(255,255,255,0.05);
    font-family: var(--sans);
    font-size: 0.62rem; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase;
    color: var(--silver-mid);
    cursor: var(--cur-hand, pointer);
    transition: background 0.22s, color 0.22s, border-color 0.22s;
}
.cm-foot:hover { background: rgba(233,201,106,0.1); border-color: rgba(233,201,106,0.4); color: var(--white); }
.cm-view { animation: cmIn 0.35s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes cmIn { from { opacity: 0; transform: translateY(8px); } }
.cm-mk { display: block; margin-bottom: 14px; --mk-size: 44px; --mk-persp: 380px; }
.cm-sigil { display: block; width: 100%; height: 100%; }
.cm .h2 { font-size: clamp(1.6rem, 4vw, 2.1rem); margin-top: 8px; }
.cm-sub {
    margin-top: 10px;
    font-family: var(--sans); font-size: 0.9rem; line-height: 1.6;
    color: var(--silver-mid);
}
.cm-sub b { color: var(--white); font-weight: 600; }

/* The mark alone sits on the centre axis; the eyebrow, heading and
   standfirst under it stay left-aligned, as does everything below.
   margin-inline rather than the margin shorthand, so .cm-mk keeps its
   own margin-bottom (the shorthand is what .cm-done uses, and it has to
   restate the 14px to avoid dropping it). */
.cm-view[data-view="menu"] > .cm-mk { margin-inline: auto; }

.cm-options { display: flex; flex-direction: column; gap: 10px; margin-top: 26px; }
.cm-opt {
    display: flex; align-items: center; gap: 16px;
    width: 100%;
    padding: 16px 18px;
    border-radius: 10px;
    border: 1px solid rgba(228,228,228,0.12);
    background: rgba(0,0,0,0.22);
    color: inherit; font: inherit; text-align: left; text-decoration: none;
    cursor: var(--cur-hand, pointer);
    transition: border-color 0.25s, background 0.25s, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.cm-opt:hover { border-color: rgba(233,201,106,0.55); background: rgba(233,201,106,0.07); transform: translateX(4px); }
.cm-ico {
    flex: none;
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(233,201,106,0.35);
    color: var(--gold-hi);
}
.cm-ico svg { width: 22px; height: 22px; stroke: currentColor; }
.cm-txt { flex: 1; min-width: 0; }
.cm-txt b { display: block; font-family: var(--serif); font-weight: 500; font-size: 1.15rem; color: var(--white); }
.cm-txt small { display: block; margin-top: 3px; font-family: var(--sans); font-size: 0.78rem; color: var(--silver-dim); }
.cm-go { flex: none; color: var(--gold-hi); font-size: 1.1rem; transition: transform 0.3s; }
.cm-opt:hover .cm-go { transform: translateX(4px); }

.cm-topics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 20px; }
.cm-topics input { position: absolute; opacity: 0; pointer-events: none; }
.cm-topics span {
    display: inline-block;
    padding: 7px 13px;
    border-radius: 999px;
    border: 1px solid rgba(228,228,228,0.16);
    font-family: var(--sans); font-size: 0.66rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--silver-mid);
    cursor: var(--cur-hand, pointer);
    transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.cm-topics span:hover { color: var(--white); border-color: rgba(233,201,106,0.5); }
.cm-topics input:checked + span { color: #2a0907; background: var(--gold-hi); border-color: var(--gold-hi); }
.cm-topics input:focus-visible + span { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
.cm-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cm-field { display: block; margin-top: 16px; }
.cm-field > span {
    display: block; margin-bottom: 6px;
    font-family: var(--sans); font-size: 0.6rem; font-weight: 600; letter-spacing: 0.24em; text-transform: uppercase;
    color: var(--gold);
}
.cm-field input, .cm-field textarea {
    width: 100%;
    padding: 12px 14px;
    border-radius: 8px;
    border: 1px solid rgba(228,228,228,0.16);
    background: rgba(0,0,0,0.3);
    color: var(--white);
    font-family: var(--sans); font-size: 0.95rem;
    outline: none;
    resize: vertical;
    transition: border-color 0.2s;
}
.cm-field textarea { min-height: 120px; line-height: 1.5; }
.cm-field input:focus, .cm-field textarea:focus { border-color: var(--gold-hi); }
.cm-field.bad input, .cm-field.bad textarea { border-color: rgba(255,120,100,0.7); }
.cm-field em, .cm-err {
    display: block;
    min-height: 1em;
    margin-top: 5px;
    font-family: var(--sans); font-size: 0.74rem; font-style: normal;
    color: #ffb4a8;
}
.cm-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* Centred on the same axis as the Back button below it. .btn is
   inline-flex, so it would otherwise sit at the left edge of the form
   while .cm-foot sat in the middle — two buttons, two alignments.
   width:fit-content keeps it from stretching once it is block-level. */
.cm-send { display: flex; width: fit-content; margin: 6px auto 0; }
.cm-send[disabled] { opacity: 0.6; pointer-events: none; }
.cm-done { text-align: center; padding: 10px 0; }
.cm-done .cm-mk { margin: 0 auto 14px; --mk-size: 64px; }
.cm-done .eyebrow { justify-content: center; }
.cm-done .h2 em { color: var(--gold-hi); }

@media (max-width: 560px) {
    .cm { padding: 12px; }
    .cm-card { padding: 28px 20px 20px; max-height: calc(100dvh - 24px); }
    .cm-row { grid-template-columns: 1fr; gap: 0; }
    .cm-opt { padding: 14px; gap: 12px; }
}
