/* ══════════════════════════════════════════════════════════════════
   Spooky Scavenger Hunt: the ornamental layer.

   Everything decorative lives in this one file, on purpose. The app's
   structure, spacing and behaviour are in ui.css and never reference
   anything here, so this layer can be retuned or thrown away without
   touching a single working screen.

   Every piece of commissioned art is a --art-* variable below. Dropping a
   real file in is a one-line change, and until one arrives each slot holds
   a drawn stand-in so no screen is blocked.
   ══════════════════════════════════════════════════════════════════ */

:root{
  /* ── art slots. Swap the value, change nothing else. ───────────── */
  /* Tiled, not stretched: it is a paper texture, so it repeats at a fixed size
     and the gradients beneath it do the shaping. Stretching a tile to cover a
     card would scale the fibres differently on every card. */
  --art-parchment: url('/art/parchment.webp');
  --parch-tile:    360px;
  --art-texture:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='4'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  --art-web:       url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170' fill='none' stroke='%23B9A7D6' stroke-width='1.05' stroke-opacity='.5'%3E%3Cpath d='M0 0 L170 62 M0 0 L120 120 M0 0 L62 170 M0 0 L18 170 M0 0 L170 18'/%3E%3Cpath d='M34 0 Q22 22 0 34 M62 0 Q40 40 0 62 M92 0 Q60 60 0 92 M124 0 Q80 80 0 124 M158 0 Q104 104 0 158'/%3E%3C/svg%3E");
  --art-gate-hero: url('/art/gate-poster.jpg');
  /* The wall. One photograph, fixed behind every screen and sized to cover,
     never tiled: a crack pattern repeats visibly at the second tile and a
     photograph has no seamless edge. On a phone it fits exactly; on a wide
     screen it is a 2x upscale of the middle band, which a texture survives.
     The darkening lives in CSS on top of it rather than baked in, so it is
     one number to tune if the type ever fights the stone. */
  --art-stone: url('/art/stone.webp');
  /* Grain squashed along one axis reads as a plank. A few hundred bytes. */
  --art-wood:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='96'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.006 0.32' numOctaves='4' seed='3'/%3E%3CfeColorMatrix values='0 0 0 0 0.62  0 0 0 0 0.42  0 0 0 0 0.26  0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='480' height='96' filter='url(%23w)'/%3E%3C/svg%3E");

  /* 9-slice frames. The corners hold still, the edges tile, the middle stays
     clear: that is what lets one painted frame wrap a panel of any height.
     --*-slice is the inset, in the FILE's own pixels, where the corner
     ornament stops and the repeatable edge begins. Get that number wrong and
     the corners stretch. */
  --art-frame:       url('/art/frame.webp');
  /* Measured off the file: the corner scrollwork boxes 82x70, so 92 takes the
     whole ornament with a little plain rail to spare. Erring high costs a few
     pixels of rail rendered at fixed size; erring low shears the scrollwork,
     which is what the dragon bar's rubies taught. */
  --art-frame-slice: 92;
  --art-frame-width: 30px;

  /* The dragon bar. Measured off the delivered file: 900x343, the beasts
     ending 189px in on the left and 188px on the right, rails 37 and 32 thick.
     STRETCH, not round: the ruby sits at the centre of the top and bottom
     rails, so repeating the edge would tile four rubies across the bar instead
     of leaving the one the artwork intends. */
  --art-bar-frame:   url('/art/bar-frame.webp');
  /* 107 and 100, not the 37 and 32 the plain rail measures: the ruby's gold
     filigree reaches three times deeper than the rail it sits on, and a slice
     cut at the rail line shears the gem in half. Slice to the ornament, never
     to the bar. */
  --art-bar-slice:   107 188 100 189;
  /* The border widths are derived from the bar's height, not typed in, so the
     dragons keep the proportions they were painted at whatever size the bar
     renders. 37/343, 189/343, 32/343. */
  --bar-h:           52px;
  --bar-w-top:       calc(var(--bar-h) * 0.312);
  --bar-w-side:      calc(var(--bar-h) * 0.551);
  --bar-w-bot:       calc(var(--bar-h) * 0.292);

  /* The card frame. Same plate, 1442x692 native, keyed off one flat magenta.
     Rails measured at 136 top, 132 bottom, 149 left, 145 right; the brass
     corners reach 278 in from every edge, roughly twice the rail, so the slice
     and the rail need separate widths and the border BOX is set to the rail.

     One scale for the whole thing, so the corners stay square and each rail
     keeps the thickness it was painted at. At 0.1 the side rails land on 15px,
     which reads as timber on a phone without eating the card. */
  --art-card-frame:  url('/art/card-frame.webp');
  --cf-slice:        278;
  --cf-s:            0.1;
  --cf-bw:           calc(278px * var(--cf-s));
  --cf-rail:         calc(136px * var(--cf-s)) calc(145px * var(--cf-s))
                     calc(132px * var(--cf-s)) calc(149px * var(--cf-s));

  /* Circular medallion behind a trial's icon. Fixed size, so nothing to slice. */
  --art-medallion: none;      /* url('/art/medallion.webp') */

  --art-fleuron:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C9A227' stroke-width='1.3' stroke-opacity='.85'%3E%3Cpath d='M12 3 C12 8 8 12 3 12 C8 12 12 16 12 21 C12 16 16 12 21 12 C16 12 12 8 12 3 Z'/%3E%3Ccircle cx='12' cy='12' r='1.6' fill='%23C9A227' stroke='none'/%3E%3C/svg%3E");

  /* ── stone, lit by torches, framed in wood. The stone photograph is
     warm, so the panels that sit on it are a shade warm too, or they float
     cool over it instead of standing against it. ──────────────────── */
  --ink:#15130F; --ink-2:#0D0C0A;
  --crypt:#24211C; --crypt-2:#2C2923; --crypt-3:#38342D;
  --line:#4A463E; --line-soft:#302D27;
  --bone:#EDE6D8; --ash:#ABA69C; --ash-2:#7B776F;
  /* Walnut, for the rails and anything that used to be a violet panel edge. */
  --wood:#30200F; --wood-2:#4A3119; --wood-3:#6B4A2C; --wood-line:#5A3C22;
  /* The one cool accent. Purple was the odd colour out on stone; steel is
     the dragon's own silver, and it still reads as "bonus" beside amber. */
  --hex:#8FB0CF; --hex-lo:#2C3A47;

  /* ── added ornament colours. The semantics in ui.css are untouched. */
  --gilt:#C9A227; --gilt-lo:#6E5714;
  --slime:#7CFF4F;            /* the sign-painted green from the reference */
  --parch:#E6D8B8; --parch-2:#CFBC93; --parch-ink:#2A2016;

  --f-t:"Pirata One","Bodoni Moda",Georgia,serif;   /* the big title only */
}

/* ── atmosphere ─────────────────────────────────────────────────── */
/* The flat ink is what shows for the half second before the photograph
   arrives, and what a browser with images off gets. */
body{background:var(--ink)}
/* The wall. A fixed pseudo-element rather than background-attachment:fixed
   on body, because iOS Safari ignores fixed attachment and sizes a cover
   background to the whole document instead of the viewport, which on a long
   feed is one crack stretched three screens tall. Top to bottom: the torch
   glow, the darkening that keeps bone type readable, the stone. */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(110% 55% at 50% -8%, rgba(244,163,64,.20) 0%, transparent 60%),
    linear-gradient(180deg, rgba(14,12,9,.58) 0%, rgba(14,12,9,.64) 60%, rgba(14,12,9,.74) 100%),
    var(--art-stone) center/cover no-repeat var(--ink);
}
body::after{content:none}
/* The rails are planks: the top bar and the tab bar share one walnut. */
.topbar{
  background:var(--art-wood),linear-gradient(180deg,var(--wood-2),var(--wood));
  background-size:480px 96px,auto;background-blend-mode:soft-light,normal;
  border-bottom:1px solid var(--wood-line);
  box-shadow:0 1px 0 rgba(255,220,170,.08) inset,0 6px 18px -10px #000;
}
body>*{position:relative;z-index:1}

/* ── the title is a painting now, so it gets a shadow instead of a face ── */
.mark .wm{filter:drop-shadow(0 1px 1px #000) drop-shadow(0 0 9px rgba(0,0,0,.8))}
.mark i{color:var(--ash-2);text-shadow:0 1px 0 #000}
.flame{filter:drop-shadow(0 0 10px rgba(244,163,64,.75))}

/* ── the clock becomes a hanging scroll ─────────────────────────── */
.clock{
  background:linear-gradient(180deg,#4A3520,#2E2013);
  border:1px solid #6B4E2A;border-radius:6px;
  box-shadow:inset 0 1px 0 rgba(255,225,170,.2),0 3px 10px -3px #000;
  color:#E7D6B4;
}
.clock b{color:#FFC15E;text-shadow:0 0 8px rgba(255,193,94,.5)}

/* ── gilt frame. One symmetric fleuron, four corners, no rotation ── */
.panel,.card,.post,.sheet{
  border:var(--art-frame-width) solid transparent;
  border-image:var(--art-frame) var(--art-frame-slice) / var(--art-frame-width) / 0 round;
  background-clip:padding-box;
  box-shadow:0 10px 26px -14px #000;
}
/* The feed is the one surface people scroll for minutes at a time, and a gilt
   frame per item turns that into a gallery wall and fights every photo in it.
   Frames stay where they earn their keep: panels, sheets, task cards. */
.post,.composer{
  border:1px solid var(--line-soft);
  border-image:none;
  border-radius:var(--r-m);
  box-shadow:0 8px 20px -16px #000;
}

/* A frame occupies the border box, so anything that drew its own edge at the
   panel's rim gives that space back rather than fighting it. */
.card>header,.sheet>header{border-bottom-color:rgba(201,162,39,.3)}
.post .shot{border-left:0;border-right:0}
.card>header,.sheet>header{
  background:linear-gradient(180deg,rgba(201,162,39,.09),transparent);
  border-bottom-color:rgba(201,162,39,.28);
}
.card>header h3,.sheet>header h3,.sechead h3{
  color:#F7EFDF;text-shadow:0 1px 0 #000,0 0 18px rgba(201,162,39,.28);
}

/* ── task cards become torn parchment ───────────────────────────── */
.tcard{
  background-image:var(--art-parchment),
    radial-gradient(120% 90% at 20% 0%,rgba(255,248,224,.8) 0%,transparent 60%),
    linear-gradient(165deg,var(--parch) 0%,var(--parch-2) 100%);
  background-size:var(--parch-tile) var(--parch-tile),cover,cover;
  background-repeat:repeat,no-repeat,no-repeat;
  background-blend-mode:multiply,normal,normal;
  /* The paper stops at the rail instead of squaring off the frame's ragged
     bark edge into a rectangle. */
  background-clip:padding-box;
  /* Timber around every trial. The border box is the rail so the paper lands
     in the opening; the border image stays wider because the brass corners
     reach about twice as deep as the rail they sit on. */
  border-style:solid;border-color:transparent;
  border-width:var(--cf-rail);
  border-image:var(--art-card-frame) var(--cf-slice) / var(--cf-bw) / 0 stretch;
  border-radius:0;
  color:var(--parch-ink);
  /* The drawn torn edge is gone. The frame is the card's edge now, and a clip
     path would cut the bark silhouette back into a polygon. The shadow follows
     the frame's own alpha, so it traces the bark rather than a rectangle. */
  filter:drop-shadow(0 7px 12px rgba(0,0,0,.55));
  padding:10px 11px;
}
.tcard:hover{background-color:#F2E7CB}
.tcard h4{color:#1E170F;font-family:"Bodoni Moda",Georgia,serif;font-weight:700;font-size:16.5px}
.tcard p{color:#5A4A33}
/* A trial's icon becomes a struck medallion: parchment disc, gilt rim, the
   glyph pressed into it. Fixed size, so this is the one slot that takes a
   plain square PNG with no slicing to worry about. */
.tcard .ic{
  border-radius:50%;
  background:var(--art-medallion),
    radial-gradient(circle at 34% 26%,#F8F0D8 0%,#DFCCA2 58%,#BFA97B 100%);
  background-size:cover;background-position:center;
  box-shadow:inset 0 0 0 2px rgba(201,162,39,.8),
             inset 0 2px 5px rgba(255,255,255,.6),
             inset 0 -3px 7px rgba(120,92,40,.32),
             0 2px 6px -1px rgba(0,0,0,.6);
  color:#3F2E14;
}
.tcard .ic svg{filter:drop-shadow(0 1px 0 rgba(255,255,255,.45))}
.tcard .pts{color:#8A3E12;font-family:"Bodoni Moda",Georgia,serif;font-weight:800;font-size:26px!important;
  text-shadow:0 1px 0 rgba(255,255,255,.4)}
.tcard .chip{background:rgba(42,32,22,.8);border-color:rgba(42,32,22,.9);color:#EFE3C8}
.tcard .chip.ok{background:#1C5A3C;border-color:#1C5A3C;color:#BFF5D8}
.tcard .chip.wait{background:#7A4712;border-color:#7A4712;color:#FFDFAE}
.tcard .chip.no{background:#6E2216;border-color:#6E2216;color:#FFD3CA}
.tcard .chip.bonus{background:#472A6B;border-color:#472A6B;color:#E4D2FF}
.tcard.sealed{background:linear-gradient(165deg,#2A1B48,#1C1132);color:var(--ash)}
.tcard.sealed h4{color:var(--ash)}
.tcard.sealed p{color:var(--ash-2)}
.tcard.sealed .pts{color:var(--ash-2)}

/* ── filters become luggage tags ────────────────────────────────── */
.filters button{
  background:linear-gradient(180deg,#EBDDBC,#CBB891);
  border:1px solid #8E7A54;color:#2A2016;font-weight:600;
  border-radius:3px 9px 9px 3px;
  box-shadow:0 2px 6px -2px #000;
}
.filters button.on{background:linear-gradient(180deg,#FFD98A,#E0A94A);border-color:#7A5A1E}

/* ── live numbers get gilded, not glowing-green ─────────────────── */
.tile .v,.who .sc b,.rankpill .n{
  font-family:"Bodoni Moda",Georgia,serif;font-weight:800;
  text-shadow:0 0 22px rgba(201,162,39,.35),0 2px 0 #000;
}
.tile{background:linear-gradient(180deg,var(--crypt-2),var(--crypt));border-color:var(--line)}
.tile .k{color:#C6B2E6;letter-spacing:.19em}

/* ── nav: the active item is lit, the rest are carved wood ──────── */
nav.tabs{
  background:var(--art-wood),linear-gradient(180deg,var(--wood-2),var(--wood));
  background-size:480px 96px,auto;background-blend-mode:soft-light,normal;
  border-top:1px solid var(--wood-line);
  box-shadow:0 1px 0 rgba(255,220,170,.08) inset}
nav.tabs button{color:#A89078}
nav.tabs button.on{color:#FFD07A;text-shadow:0 0 12px rgba(255,208,122,.6)}
nav.tabs button.on svg{filter:drop-shadow(0 0 7px rgba(255,208,122,.7))}
.htabs{border-bottom-color:var(--wood-line)}
.htabs button.on{color:var(--candle);border-bottom-color:var(--candle);
  text-shadow:0 0 10px rgba(244,163,64,.45)}

/* ── buttons pick up a struck-metal edge ───────────────────────── */
.btn{box-shadow:inset 0 1px 0 rgba(255,255,255,.09),0 2px 7px -3px #000}
.btn.go{background:linear-gradient(180deg,#FFBE5E,#E08A22);border-color:#7A4C16;
  text-shadow:0 1px 0 rgba(255,255,255,.35)}
.btn.yes{background:linear-gradient(180deg,#8CF0BE,#3FBF8A);border-color:#1C5A3C}

/* ── leaderboard rows sit in an iron rail ──────────────────────── */
.lb{background:linear-gradient(180deg,rgba(58,31,100,.5),rgba(35,17,65,.5));
  border:1px solid var(--line-soft);border-left:3px solid transparent}
.lb.me{border-left-color:var(--gilt)}
.lb .rk.top{color:var(--gilt);text-shadow:0 0 12px rgba(201,162,39,.6)}

/* ── the hoard meter keeps its glow, just warmer surroundings ──── */
.meter .num b{text-shadow:0 0 18px rgba(255,180,70,.6)}

/* ── banners ───────────────────────────────────────────────────── */
.banner.queued{background:linear-gradient(180deg,rgba(122,76,22,.35),rgba(46,28,10,.35));
  border-color:#8A5A1E}
.banner b{font-family:"Bodoni Moda",Georgia,serif}

@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ══ the front door ═══════════════════════════════════════════════
   The first screen a guest ever sees, so it carries the most ornament.
   --art-gate-hero drops a painted backdrop in behind the drawn skyline;
   until then the skyline is the art. Either way the form below keeps its
   own ground, so nothing decorative ever sits under a text run. */
body.gating .topbar{display:none}
/* The gate's own glow is stronger: there is no wood rail up there to carry
   the torches, and the parchment card wants light to sit in. */
body.gating::before{
  background:
    radial-gradient(130% 60% at 50% 0%, rgba(244,163,64,.26) 0%, rgba(244,163,64,.06) 42%, transparent 72%),
    linear-gradient(180deg, rgba(14,12,9,.54) 0%, rgba(14,12,9,.70) 100%),
    var(--art-stone) center/cover no-repeat var(--ink)}

/* The art goes on the scene row, never the hero. The hero also holds the
   wordmark, and a full-bleed backdrop behind it puts lit windows under type,
   which is the fault the reference renders show and the one the drawn skyline
   already had to be rescued from. */
.gate-scene{
  background-image:var(--art-gate-hero);
  background-size:cover;
  /* The gate still, the same castle the front door opens with. Anchored a
     third down so the arch and both banners sit in the band; the form below brings
     its own ground. */
  background-position:center 32%;
  /* Masked rather than scrimmed. A gradient overlay would have to guess the
     colour behind it; a mask lets the page's own ground show through, so the
     scene fades in under the wordmark with no seam and no colour to match. */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 17%,#000 92%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 17%,#000 92%,transparent 100%);
}
/* The drawn skyline stays until real art lands, at which point it is deleted
   from gateView() rather than hidden. There is no CSS selector that can see
   whether a custom property is set, and a rule that quietly never matches is
   worse than no rule. */
.gate-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  /* Only the last sliver darkens, where the scene meets the card. Any more and
     it swallows the silhouette it is supposed to be sitting behind. */
  background:linear-gradient(to bottom,transparent 82%,rgba(20,20,23,.7) 96%,var(--ink) 100%);
}
.gate-mark h1{
  font-family:var(--f-t);font-weight:400;letter-spacing:.02em;color:#F7F0E2;
  text-shadow:0 0 6px rgba(124,255,79,.55),0 0 22px rgba(124,255,79,.3),
              0 3px 0 #1A0E2C,0 6px 18px rgba(0,0,0,.8);
}
.gate-mark .sub{color:#C0AEDC;text-shadow:0 1px 0 #000}
.gate-mark .bigflame{filter:drop-shadow(0 0 16px rgba(244,163,64,.8))}

/* the form sits on parchment inside a gilt frame, like everything else */
.gate-card{
  color:var(--parch-ink);
  border:1px solid #8E7A54;border-radius:3px;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.25),
             inset 0 0 44px rgba(120,92,40,.18),
             0 16px 34px -14px #000;
  background-image:var(--art-fleuron),var(--art-fleuron),var(--art-fleuron),var(--art-fleuron),
    var(--art-parchment),
    radial-gradient(130% 80% at 22% 0%,rgba(255,248,224,.85) 0%,transparent 62%),
    linear-gradient(168deg,var(--parch) 0%,var(--parch-2) 100%);
  background-position:left 7px top 7px,right 7px top 7px,left 7px bottom 7px,right 7px bottom 7px,
    center,center,center;
  background-size:16px 16px,16px 16px,16px 16px,16px 16px,
    var(--parch-tile) var(--parch-tile),cover,cover;
  background-repeat:no-repeat,no-repeat,no-repeat,no-repeat,repeat,no-repeat,no-repeat;
  background-blend-mode:normal,normal,normal,normal,multiply,normal,normal;
}
.gate-card h2{color:#1E170F;font-family:"Bodoni Moda",Georgia,serif;font-weight:700}
.gate-card .lede{color:#5A4A33}
.gate-card label.fl>span{color:#6B5940}
.gate-card .check{color:#3A2E1E}
.gate-card .dots i{background:rgba(42,32,22,.2)}
.gate-card .dots i.on{background:#B4762A}

/* recessed cream fields, the way a filled-in ledger reads */
.gate-card input,.gate-card select,.gate-card textarea{
  background:#FBF5E4;border:1px solid #A8906A;color:#231A0F;
  box-shadow:inset 0 2px 4px rgba(120,92,40,.22);
}
.gate-card input::placeholder{color:#A4937A}
.gate-card input:focus-visible,.gate-card select:focus-visible,.gate-card textarea:focus-visible{
  outline-color:#B4762A;background:#FFFCF2}

.gate-card .btn{color:#2A2016;background:linear-gradient(180deg,#E9DBBA,#CDB88F);
  border-color:#8E7A54;box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 2px 6px -2px rgba(0,0,0,.5)}
.gate-card .btn.go{background:linear-gradient(180deg,#FFC463,#DE8C1E);border-color:#7A4C16;color:#2A1B08}
.gate-card .teampick button{background:#F4EBD3;border-color:#A8906A;color:#2A2016}
.gate-card .teampick button.on{background:#FFE7B4;border-color:#B4762A}
.gate-card .teampick .sub{color:#7A674A}
.gate-card .swatches button.on{border-color:#4A3A22}
.gate-card .rule b{color:#1E170F}
.gate-card .rule span{color:#5A4A33}
.gate-card .rule .n{color:#A85E12}

/* ornate divider: two gilt rules with a fleuron breathing between them */
.rule-orn{background:var(--art-fleuron) center/15px 15px no-repeat}
.rule-orn::before{background:linear-gradient(90deg,transparent,rgba(120,92,40,.55))}
.rule-orn::after{background:linear-gradient(90deg,rgba(120,92,40,.55),transparent)}

/* ══ the progress bar ═════════════════════════════════════════════
   The plate is art and the molten fill inside is code; neither knows about
   the other, which is why swapping one has never cost the other anything.

   --art-bar-frame is the pair of dragons this was drawn with. They are off
   now because the hunt is not a dragon hunt, and two of them flanking a
   progress bar is the loudest theming left on the screen. The file is still
   in /art and still measured correctly above: putting it back is restoring
   the border-image line below, and nothing else moves. */
.meter{
  height:var(--bar-h);
  border:1px solid rgba(201,162,39,.45);
  border-radius:9px;
  background:linear-gradient(180deg,rgba(201,162,39,.09),rgba(0,0,0,.25));
  box-shadow:inset 0 1px 0 rgba(255,225,170,.18),0 6px 16px -10px #000;
  padding:0 13px;gap:12px;
}
@media(max-width:430px){:root{--bar-h:48px}}
.meter .num b{font-size:17px}
.meter .num span{margin-top:3px}
/* The compact meter on a leaderboard row stays bare. At 74px wide a frame is
   all frame and no bar. */
.lb .meter{border:0;background:none;padding:0;height:auto}

