/* ==========================================================================
   Local iPad Darts - stylesheet
   Dark, high contrast, big touch targets, landscape-first game screen.
   ========================================================================== */

/* Any author `display` beats the browser's own [hidden] rule, so anything laid
   out as flex or grid stays on screen - and, worse, keeps swallowing taps -
   however many times the markup says hidden. This has been patched one
   element at a time three times already; say it once instead. */
[hidden]{display:none !important}

:root{
  --bg:#080B10;
  --bg2:#0E141C;
  --surface:rgba(255,255,255,.045);
  --surface2:rgba(255,255,255,.075);
  --line:rgba(255,255,255,.09);
  --line2:rgba(255,255,255,.16);
  --ink:#EAF1F8;
  --muted:#8797AA;
  --dim:#5D6B7C;

  --green:#39FF6A;
  --green-dk:#12351F;
  --red:#FF3B5C;
  --red-dk:#3A1119;
  --gold:#FFC93B;
  --blue:#3BC8FF;
  --purple:#B96BFF;

  --r-sm:10px;
  --r:16px;
  --r-lg:24px;
  --shadow:0 18px 44px rgba(0,0,0,.55);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Inter, Roboto, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}

html,body{height:100%}
body{
  margin:0;
  font-family:var(--font);
  color:var(--ink);
  background:var(--bg);
  background-image:
    radial-gradient(1100px 600px at 15% -10%, #16202C 0%, transparent 60%),
    radial-gradient(900px 500px at 95% 0%, #1A1524 0%, transparent 55%),
    linear-gradient(180deg,#080B10 0%,#0B1017 100%);
  background-attachment:fixed;
  -webkit-font-smoothing:antialiased;
  overscroll-behavior:none;
}

/* soft ambient glows ----------------------------------------------------- */
.glow{position:fixed;border-radius:50%;filter:blur(90px);pointer-events:none;z-index:0;opacity:.16}
.glow-a{width:520px;height:520px;background:var(--green);top:-220px;left:-140px}
.glow-b{width:460px;height:460px;background:var(--red);bottom:-220px;right:-160px;opacity:.13}

main,.topbar,.flashes{position:relative;z-index:1}

a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;font-weight:800;letter-spacing:-.02em}
h1{font-size:clamp(28px,4vw,44px)}
h2{font-size:clamp(20px,2.4vw,26px)}
h3{font-size:17px}
p{margin:0 0 12px}

.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}

/* ==========================================================================
   Top bar
   ========================================================================== */
.topbar{
  display:flex;align-items:center;gap:20px;
  padding:14px clamp(16px,3vw,32px);
  border-bottom:1px solid var(--line);
  background:rgba(8,11,16,.72);
  backdrop-filter:saturate(160%) blur(18px);
  -webkit-backdrop-filter:saturate(160%) blur(18px);
  position:sticky;top:0;z-index:40;
}
.brand{display:flex;align-items:center;gap:11px;font-weight:900;letter-spacing:.18em;font-size:15px}
.brand-mark{width:30px;height:30px;flex:none}
.brand-name{background:linear-gradient(92deg,var(--green),var(--blue));-webkit-background-clip:text;background-clip:text;color:transparent}
.topnav{display:flex;gap:4px;margin-left:auto;flex-wrap:wrap}
.topnav a{
  padding:9px 15px;border-radius:999px;font-weight:700;font-size:14px;color:var(--muted);
  border:1px solid transparent;transition:.16s;
}
.topnav a:hover{color:var(--ink);background:var(--surface)}
.topnav a.on{color:var(--green);background:rgba(57,255,106,.09);border-color:rgba(57,255,106,.28)}

/* On a phone the tab row wraps to three cramped lines and eats the screen, so
   below 640px it becomes a dropdown. Tablets and desktops keep the tabs: there
   is room for them there, and a visible row beats a hidden one every time.
   Everything here is gated on .js - without scripting the button would not
   open and the nav must stay a plain row of links. */
.navtoggle{display:none}
.navtoggle .bars{display:inline-flex;flex-direction:column;justify-content:center;gap:4px;width:16px}
.navtoggle .bars i{display:block;height:2px;border-radius:2px;background:currentColor;
  transition:transform .18s, opacity .18s}
.navtoggle[aria-expanded="true"] .bars i:nth-child(1){transform:translateY(6px) rotate(45deg)}
.navtoggle[aria-expanded="true"] .bars i:nth-child(2){opacity:0}
.navtoggle[aria-expanded="true"] .bars i:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

@media (max-width:640px){
  .js .navtoggle{
    display:inline-flex;align-items:center;gap:9px;margin-left:auto;
    padding:9px 14px;border-radius:999px;font:inherit;font-weight:800;font-size:14px;
    color:var(--ink);background:var(--surface);border:1px solid var(--line);cursor:pointer;
  }
  .js .navtoggle[aria-expanded="true"]{border-color:rgba(57,255,106,.35);color:var(--green)}
  .js .topnav{
    position:absolute;top:100%;left:clamp(16px,3vw,32px);right:clamp(16px,3vw,32px);
    margin:8px 0 0;padding:8px;flex-direction:column;gap:2px;flex-wrap:nowrap;
    /* An opaque colour, not var(--surface): the surface tokens are 4-7% white
       washes designed to sit *on* the page background. A panel floating over
       the page has to bring its own, or you read the hero text through it. */
    background:var(--bg2);
    border:1px solid var(--line2);border-radius:14px;
    box-shadow:0 26px 60px rgba(0,0,0,.7);
    z-index:41;                     /* above the flash messages underneath */
    display:none;
  }
  .js .topnav.open{display:flex}
  /* an open menu outranks a passing toast */
  .js .topbar.navopen{z-index:95}
  .js .topnav a{padding:13px 14px;border-radius:10px;font-size:15px;border:0}
  .js .topnav a.on{background:rgba(57,255,106,.10)}
  .js .topnav a.navme{max-width:none;order:99;margin-top:4px;
    border-top:1px solid var(--line);border-radius:0 0 8px 8px}
}
@media (prefers-reduced-motion:reduce){ .navtoggle .bars i{transition:none} }

/* ==========================================================================
   Layout
   ========================================================================== */
.wrap{max-width:1240px;margin:0 auto;padding:clamp(18px,3vw,36px) clamp(16px,3vw,32px) 80px}
.wide{max-width:1500px;margin:0 auto;padding:clamp(18px,3vw,32px) clamp(16px,3vw,28px) 60px}
.page-head{display:flex;align-items:flex-end;gap:18px;flex-wrap:wrap;margin-bottom:26px}
.page-head .sub{color:var(--muted);font-size:15px;margin-top:6px}
.spacer{flex:1}

.grid{display:grid;gap:14px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}

/* ==========================================================================
   Cards / panels
   ========================================================================== */
.card{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r);
  padding:18px;
  backdrop-filter:blur(10px);
}
.card.pad-lg{padding:24px}
.card h3{margin-bottom:14px;font-size:13px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);font-weight:800}

.stat{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:16px 18px;display:flex;flex-direction:column;gap:4px;min-height:92px;justify-content:center;
}
.stat .k{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--muted);font-weight:800}
.stat .v{font-size:clamp(24px,3vw,32px);font-weight:900;letter-spacing:-.03em}
.stat .v small{font-size:15px;color:var(--muted);font-weight:700;margin-left:3px}
.stat.accent .v{color:var(--green)}
.stat.warn .v{color:var(--gold)}
.stat.bad .v{color:var(--red)}

.kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line)}
.kv:last-child{border-bottom:0}
.kv .k{color:var(--muted);font-size:14px}
.kv .v{font-weight:800;font-size:15px}

/* Tiny dependency-free activity chart used by the admin dashboard. */
.spark{height:150px;display:flex;align-items:flex-end;gap:clamp(2px,.55vw,7px);
  padding:10px 4px 0;border-bottom:1px solid var(--line)}
.spark .sbar{display:block;flex:1;height:max(3px,var(--h));min-width:2px;
  border-radius:4px 4px 1px 1px;background:linear-gradient(180deg,var(--green),var(--blue));
  opacity:.88}
.spark .sbar.zero{height:3px;background:var(--line2);opacity:.55}
.spark-axis{display:flex;align-items:center;margin-top:7px}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:14px 22px;border-radius:var(--r-sm);border:1px solid var(--line2);
  background:var(--surface2);color:var(--ink);font-weight:800;font-size:15px;
  cursor:pointer;transition:transform .1s,background .16s,border-color .16s;
  font-family:inherit;min-height:50px;
}
.btn:active{transform:scale(.97)}
.btn:hover{background:rgba(255,255,255,.11)}
.btn-primary{
  background:linear-gradient(180deg,#4BFF7C,#22D954);color:#05130A;border-color:transparent;
  box-shadow:0 8px 26px rgba(57,255,106,.28);
}
.btn-primary:hover{background:linear-gradient(180deg,#5CFF8A,#2AE55E)}
.btn-danger{background:rgba(255,59,92,.14);border-color:rgba(255,59,92,.4);color:#FF8098}
.btn-danger:hover{background:rgba(255,59,92,.22)}
.btn-ghost{background:transparent}
.btn-sm{padding:9px 15px;min-height:40px;font-size:13px}
.btn-lg{padding:20px 32px;font-size:19px;min-height:66px}
.btn-block{width:100%}
.btn[disabled]{opacity:.35;pointer-events:none}

/* ==========================================================================
   Home
   ========================================================================== */
.hero{text-align:center;padding:clamp(20px,5vh,60px) 0 clamp(24px,4vh,44px)}
.hero .eyebrow{letter-spacing:.34em;font-size:12px;color:var(--green);font-weight:800;margin-bottom:14px}
.hero h1{font-size:clamp(44px,9vw,92px);line-height:.94;letter-spacing:-.045em}
.hero h1 em{font-style:normal;background:linear-gradient(94deg,var(--green),var(--blue) 55%,var(--purple));-webkit-background-clip:text;background-clip:text;color:transparent}
.hero .tag{color:var(--muted);margin-top:16px;font-size:17px}

.menu{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:14px;margin-top:8px}
.menu a{
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 22px;
  background:var(--surface);min-height:150px;display:flex;flex-direction:column;justify-content:flex-end;
  transition:transform .16s,border-color .16s,background .16s;
}
.menu a:hover{transform:translateY(-3px);border-color:var(--line2);background:var(--surface2)}
.menu a:active{transform:scale(.985)}
.menu a .mi{font-size:30px;margin-bottom:auto;opacity:.95}
.menu a .mt{font-size:24px;font-weight:900;letter-spacing:-.02em}
.menu a .ms{color:var(--muted);font-size:13.5px;margin-top:5px}
.menu a.primary{
  grid-column:span 2;min-height:210px;
  background:linear-gradient(135deg,rgba(57,255,106,.16),rgba(59,200,255,.07));
  border-color:rgba(57,255,106,.34);
}
.menu a.primary .mt{font-size:clamp(38px,5vw,54px)}
.menu a.primary::after{
  content:"";position:absolute;right:-60px;top:-60px;width:250px;height:250px;border-radius:50%;
  background:radial-gradient(circle,rgba(57,255,106,.28),transparent 68%);
}
@media (max-width:640px){.menu a.primary{grid-column:span 1;min-height:160px}}

.lan-note{
  margin-top:26px;text-align:center;color:var(--dim);font-size:13px;
}
.lan-note code{color:var(--green);font-family:var(--mono)}

/* ==========================================================================
   Avatars
   ========================================================================== */
.av{
  --sz:48px;
  width:var(--sz);height:var(--sz);border-radius:50%;flex:none;
  display:grid;place-items:center;overflow:hidden;position:relative;
  background:linear-gradient(150deg,#1B2531,#131A23);
  border:2px solid var(--line2);
  font-weight:900;letter-spacing:.02em;color:var(--muted);
  font-size:calc(var(--sz) * .36);
}
.av img{width:100%;height:100%;object-fit:cover;display:block}
.av.xs{--sz:30px}
.av.sm{--sz:40px}
.av.md{--sz:60px}
.av.lg{--sz:92px}
.av.xl{--sz:150px}
.av.ring{box-shadow:0 0 0 3px rgba(57,255,106,.28)}

/* ==========================================================================
   Player list / profile
   ========================================================================== */
.player-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}
.player-card{
  display:flex;align-items:center;gap:14px;padding:16px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);transition:.16s;
}
.player-card:hover{background:var(--surface2);border-color:var(--line2);transform:translateY(-2px)}
.player-card .nm{font-weight:800;font-size:18px}
.player-card .mt{color:var(--muted);font-size:13px;margin-top:3px}

.profile-head{display:flex;gap:24px;align-items:center;flex-wrap:wrap;margin-bottom:28px}
.profile-head h1{font-size:clamp(30px,5vw,48px)}

/* photo picker ----------------------------------------------------------- */
.photo-pick{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.photo-drop{
  position:relative;width:118px;height:118px;border-radius:50%;
  border:2px dashed var(--line2);display:grid;place-items:center;cursor:pointer;
  background:var(--surface);overflow:hidden;transition:.16s;flex:none;
}
.photo-drop:hover,.photo-drop.over{border-color:var(--green);background:rgba(57,255,106,.07)}
.photo-drop img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.photo-drop .ph{text-align:center;color:var(--dim);font-size:11px;font-weight:800;letter-spacing:.08em;padding:0 10px;line-height:1.5}
.photo-drop .ph b{display:block;font-size:26px;margin-bottom:4px;color:var(--muted)}
.photo-drop input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer}
.photo-hint{color:var(--muted);font-size:13px;max-width:280px;line-height:1.55}

.colour-row{display:flex;gap:9px;flex-wrap:wrap;margin-top:6px}
.colour-row label{
  width:34px;height:34px;border-radius:50%;cursor:pointer;position:relative;
  border:2px solid transparent;transition:.14s;
}
.colour-row input{position:absolute;opacity:0}
.colour-row input:checked + span{box-shadow:0 0 0 3px rgba(255,255,255,.85)}
.colour-row span{position:absolute;inset:0;border-radius:50%}

/* ==========================================================================
   Forms
   ========================================================================== */
label.fl{display:block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800;margin-bottom:7px}
/* Every typed field, not just the text ones. Listing only [type=text] left
   the password box on the sign-in page, the address on the contact form and
   the message textarea as browser-default white rectangles on a dark site -
   the front door included. Enumerated rather than a bare `input` so that
   checkboxes, radios and file pickers keep their native controls. */
input[type=text],input[type=search],input[type=date],input[type=email],
input[type=password],input[type=number],input[type=tel],input[type=url],
textarea,select{
  width:100%;padding:14px 16px;border-radius:var(--r-sm);
  background:rgba(0,0,0,.32);border:1px solid var(--line2);color:var(--ink);
  font-size:16px;font-family:inherit;font-weight:600;min-height:50px;
}
textarea{line-height:1.5;resize:vertical}
input[type=search]{appearance:none;-webkit-appearance:none}
input[type=search]::-webkit-search-cancel-button{
  -webkit-appearance:none;width:14px;height:14px;cursor:pointer;opacity:.55;
  background:currentColor;
  -webkit-mask:linear-gradient(currentColor,currentColor) center/14px 2px no-repeat,
               linear-gradient(currentColor,currentColor) center/2px 14px no-repeat;
  transform:rotate(45deg);
}
input[type=search]::-webkit-search-cancel-button:hover{opacity:1}
input[type=text]:focus,input[type=search]:focus,select:focus,
input[type=date]:focus,input[type=email]:focus,input[type=password]:focus,
input[type=number]:focus,input[type=tel]:focus,input[type=url]:focus,
textarea:focus{outline:none;border-color:var(--green);box-shadow:0 0 0 3px rgba(57,255,106,.14)}
select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 20px) 22px,calc(100% - 14px) 22px;background-size:6px 6px;background-repeat:no-repeat}
.form-row{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end}
.form-row > *{flex:1;min-width:150px}
.form-row .narrow{flex:0 0 auto;min-width:0}

/* ==========================================================================
   Flash messages
   ========================================================================== */
.flashes{position:fixed;top:74px;right:18px;z-index:90;display:flex;flex-direction:column;gap:8px;max-width:min(420px,88vw)}
.flash{padding:13px 17px;border-radius:var(--r-sm);font-weight:700;font-size:14px;box-shadow:var(--shadow);
  background:#141C26;border:1px solid var(--line2);animation:slidein .3s ease both}
.flash-success{border-color:rgba(57,255,106,.45);color:var(--green)}
.flash-error{border-color:rgba(255,59,92,.5);color:#FF7C94}
@keyframes slidein{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}

/* ==========================================================================
   Chips / pills / segmented controls
   ========================================================================== */
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip{
  padding:9px 15px;border-radius:999px;border:1px solid var(--line2);
  background:var(--surface);font-size:13.5px;font-weight:700;color:var(--muted);cursor:pointer;transition:.14s;
}
.chip:hover{color:var(--ink)}
.chip.on{background:rgba(57,255,106,.13);border-color:rgba(57,255,106,.45);color:var(--green)}

.pill{display:inline-block;padding:4px 11px;border-radius:999px;font-size:11.5px;font-weight:800;letter-spacing:.05em;
  background:var(--surface2);border:1px solid var(--line);color:var(--muted)}
.pill.green{background:rgba(57,255,106,.13);border-color:rgba(57,255,106,.35);color:var(--green)}
.pill.red{background:rgba(255,59,92,.13);border-color:rgba(255,59,92,.35);color:#FF7C94}
.pill.gold{background:rgba(255,201,59,.13);border-color:rgba(255,201,59,.35);color:var(--gold)}

.seg{display:flex;gap:6px;background:rgba(0,0,0,.3);padding:5px;border-radius:14px;border:1px solid var(--line)}
.seg button,.seg label{
  flex:1;padding:13px 16px;border-radius:10px;border:0;background:transparent;color:var(--muted);
  font-weight:800;font-size:15px;cursor:pointer;font-family:inherit;text-align:center;transition:.14s;min-height:48px;
}
.seg .on,.seg input:checked + span{background:var(--surface2);color:var(--ink)}
.seg input{position:absolute;opacity:0;pointer-events:none}
.seg label{position:relative;padding:0}
.seg label span{display:block;padding:13px 16px;border-radius:10px;transition:.14s}

/* ==========================================================================
   Tables
   ========================================================================== */
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:var(--r);border:1px solid var(--line)}
table{width:100%;border-collapse:collapse;font-size:14px;min-width:480px}
th{
  text-align:left;padding:12px 14px;font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);font-weight:800;background:rgba(255,255,255,.03);border-bottom:1px solid var(--line);
  position:sticky;top:0;
}
td{padding:11px 14px;border-bottom:1px solid rgba(255,255,255,.05)}
tr:last-child td{border-bottom:0}
tbody tr:hover{background:rgba(255,255,255,.028)}
td.r,th.r{text-align:right}
.bar{position:relative;height:8px;border-radius:4px;background:rgba(255,255,255,.07);overflow:hidden;min-width:60px}
.bar i{position:absolute;inset:0 auto 0 0;border-radius:4px;background:linear-gradient(90deg,var(--green),var(--blue))}
.bar.red i{background:linear-gradient(90deg,var(--red),var(--gold))}

/* ==========================================================================
   GAME SCREEN - landscape first, no scrolling while throwing
   ========================================================================== */
body.playing{overflow:hidden;position:fixed;inset:0;width:100%}

.game{
  height:100dvh;display:grid;
  /* scorebar, the whose-turn banner, then the board */
  grid-template-rows:auto auto minmax(0,1fr);
  /* One column, and it may be narrower than its contents want to be.
     Without this the column is implicit, sizes itself to max-content, and a
     row of player cards - which carry a 132px minimum each - made the whole
     screen 556px wide on a 400px phone. The body is position:fixed, so the
     overflow could not even be scrolled to: from three players up, the right
     of every panel was simply gone. */
  grid-template-columns:minmax(0,1fr);
  padding:max(8px,env(safe-area-inset-top)) max(10px,env(safe-area-inset-right)) max(8px,env(safe-area-inset-bottom)) max(10px,env(safe-area-inset-left));
  gap:8px;
}

/* --- score strip -------------------------------------------------------- */
.scorebar{display:flex;gap:8px;align-items:stretch;min-height:0}
.scorebar .players{display:flex;gap:8px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none}
.scorebar .players::-webkit-scrollbar{display:none}

.pcard{
  flex:1 1 0;min-width:132px;display:flex;align-items:center;gap:11px;
  padding:9px 13px;border-radius:14px;background:var(--surface);border:1px solid var(--line);
  transition:.2s;position:relative;overflow:hidden;
}
.pcard .meta{min-width:0;flex:1}
/* name, score and the line under them are separate rows - as plain inline
   spans they ran together and read as "Luca421avg 120.0" */
.pcard .meta > *{display:block}
.pcard .meta > .ls{display:flex}
.pcard .nm{font-weight:800;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--muted)}
.pcard .sc{font-size:clamp(26px,3.4vw,40px);font-weight:900;letter-spacing:-.045em;line-height:1}
.pcard .av{--sz:38px}
.pcard .tiny{font-size:11px;color:var(--dim);font-weight:700;margin-top:2px}
/* Out of the game, still on the board: you have to be able to see that the
   number is spoken for, or somebody throws at it all night. */
.pcard.out{opacity:.42}
.pcard.out .sc{text-decoration:line-through}
.pcard.active{
  background:linear-gradient(135deg,rgba(57,255,106,.15),rgba(57,255,106,.03));
  border-color:rgba(57,255,106,.5);
  box-shadow:0 0 0 1px rgba(57,255,106,.18),0 10px 30px rgba(57,255,106,.14);
}
.pcard.active .nm{color:var(--green)}
.pcard.active .sc{color:#fff}
.pcard.active .av{border-color:rgba(57,255,106,.7)}
.pcard.active::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--green);
}
.pcard.winner{border-color:var(--gold);background:rgba(255,201,59,.1)}

.exitbtn{
  flex:none;width:52px;border-radius:14px;border:1px solid var(--line);background:var(--surface);
  color:var(--muted);font-size:20px;font-weight:800;cursor:pointer;
}

/* the caller's on/off switch, next to the way out */
.callerbtn{
  flex:none;width:52px;border-radius:14px;cursor:pointer;
  display:grid;place-items:center;
  border:1px solid color-mix(in srgb, var(--green) 45%, transparent);
  background:color-mix(in srgb, var(--green) 12%, var(--surface));
  color:var(--green);
}
.callerbtn svg{width:22px;height:22px;display:block}
.callerbtn.off{
  border-color:var(--line);background:var(--surface);color:var(--dim);
}
/* switched off, the sound waves go with the sound */
.callerbtn.off .wave1,.callerbtn.off .wave2{display:none}
.callerbtn.off::after{
  content:"";position:absolute;width:30px;height:2px;border-radius:2px;
  background:var(--dim);transform:rotate(-45deg);
}
.callerbtn{position:relative}

/* --- main play area ----------------------------------------------------- */
.play{display:grid;grid-template-columns:minmax(210px,.85fr) minmax(0,2.15fr);gap:8px;min-height:0}

.leftcol{display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:8px;min-height:0}

.bigscore{
  background:linear-gradient(160deg,rgba(255,255,255,.07),rgba(255,255,255,.02));
  border:1px solid var(--line2);border-radius:18px;padding:12px 16px;text-align:center;
  display:flex;flex-direction:column;justify-content:center;
}
.bigscore .lbl{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);font-weight:800}
.bigscore .val{font-size:clamp(52px,9vh,92px);font-weight:900;letter-spacing:-.055em;line-height:.9;margin:4px 0 2px}
.bigscore .who{font-size:14px;font-weight:800;color:var(--green);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bigscore.rtc .val{font-size:clamp(40px,7vh,72px);color:var(--gold)}
.bigscore .bonusturn{
  align-self:center;margin-top:6px;padding:2px 9px;border-radius:999px;
  font-size:9.5px;font-weight:900;letter-spacing:.16em;
  color:#0B0E12;background:var(--gold);
}
/* Being armed is good news that comes with a bill - your own double now costs
   you a life - so it is not the same gold as a bonus turn. */
.bigscore .bonusturn.killer{background:#FF3B5C;color:#fff}

.visitbox{
  background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:12px;
  display:flex;flex-direction:column;gap:8px;min-height:0;
}
.visitbox .hd{display:flex;justify-content:space-between;align-items:center;
  font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:800}
.darts{display:flex;gap:6px;flex:1;min-height:0}
.dartslot{
  flex:1;border-radius:12px;border:1px dashed var(--line2);display:grid;place-items:center;
  font-weight:900;font-size:clamp(15px,2.4vh,21px);color:var(--dim);background:rgba(0,0,0,.2);min-height:46px;
}
.dartslot.filled{border-style:solid;border-color:rgba(57,255,106,.4);background:rgba(57,255,106,.1);color:#fff}
/* Tapped, not yet acknowledged. Drawn immediately so the pad answers the
   finger rather than the network; deliberately dimmer than a confirmed dart,
   so a connection that never answers looks unfinished instead of silent. */
.dartslot.pending{
  border-style:solid;border-color:rgba(57,255,106,.22);
  background:rgba(57,255,106,.05);color:rgba(255,255,255,.62);
}
.dartslot.bust{border-color:rgba(255,59,92,.55);background:rgba(255,59,92,.14);color:#FF8098}
.dartslot.hit{border-color:rgba(255,201,59,.6);background:rgba(255,201,59,.14);color:var(--gold)}
.visitbox .foot{display:flex;justify-content:space-between;align-items:baseline}
.visitbox .foot .vs{font-size:26px;font-weight:900;letter-spacing:-.03em}
.visitbox .foot .dl{font-size:12px;color:var(--muted);font-weight:700}

.checkout{
  background:linear-gradient(135deg,rgba(255,201,59,.13),rgba(255,201,59,.03));
  border:1px solid rgba(255,201,59,.32);border-radius:16px;padding:11px 14px;
}
.checkout .lbl{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--gold);font-weight:800;margin-bottom:6px}
.checkout .route{font-size:clamp(16px,2.5vh,22px);font-weight:900;letter-spacing:-.01em;line-height:1.35}
.checkout .route.alt{font-size:13.5px;color:var(--muted);font-weight:700;margin-top:3px}
.checkout .note{font-size:11.5px;color:var(--muted);margin-top:6px;line-height:1.45}
.checkout.empty{background:var(--surface);border-color:var(--line);opacity:.55}
.checkout.empty .lbl{color:var(--muted)}

/* --- keypad ------------------------------------------------------------- */
/* Banner at the top, MISS and UNDO at the bottom, the keypad between them.
   space-between rather than the default, so a capped keypad leaves balanced
   room rather than a single hole under it. */
.pad{display:flex;flex-direction:column;gap:8px;min-height:0;justify-content:space-between}
#boardPad{flex:1 1 auto;min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:8px}
/* With the SINGLE/DOUBLE/TREBLE row gone there are two items, not three, and
   grid places them in the first two tracks - numbers into the auto one. Drop
   the track the row was using and the numbers keep the space they had. */
#boardPad.nomults{grid-template-rows:minmax(0,1fr) auto}
.pad button{
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
  -webkit-user-select:none;user-select:none;
}
.mults{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.mult{
  border-radius:14px;border:1px solid var(--line2);background:var(--surface);color:var(--ink);
  font-weight:900;font-size:clamp(14px,2.2vh,18px);letter-spacing:.04em;cursor:pointer;font-family:inherit;
  padding:10px 4px;min-height:clamp(44px,7vh,60px);
  transition:background-color .08s,border-color .08s,color .08s;
}
.mult:active{transform:scale(.96)}
.mult[data-m="1"].on{background:rgba(234,241,248,.16);border-color:#fff;color:#fff}
.mult[data-m="2"].on{background:rgba(59,200,255,.22);border-color:var(--blue);color:var(--blue)}
.mult[data-m="3"].on{background:rgba(255,201,59,.22);border-color:var(--gold);color:var(--gold)}
.mult.miss{background:rgba(255,59,92,.14);border-color:rgba(255,59,92,.38);color:#FF8098}
.mult.miss:hover{background:rgba(255,59,92,.22)}

.numbers{display:grid;grid-template-columns:repeat(5,1fr);grid-template-rows:repeat(4,minmax(0,1fr));gap:7px;min-height:0}
/* The same board inside a setup card, which has no height to divide up - so
   the rows size themselves and the buttons carry their own. */
.numbers.killerpad{grid-template-rows:none;margin-top:10px}
.numbers.killerpad button{min-height:46px;font-size:18px}
.numbers.killerpad button:disabled{opacity:.28;cursor:not-allowed}
.numbers button{
  border-radius:14px;border:1px solid var(--line);background:var(--surface2);color:var(--ink);
  font-weight:900;font-size:clamp(18px,3.6vh,30px);letter-spacing:-.02em;cursor:pointer;font-family:inherit;
  transition:background-color .06s,border-color .06s,color .06s;min-height:0;position:relative;
}
.numbers button:active{transform:scale(.94)}
.numbers button:hover{background:rgba(255,255,255,.13)}
.numbers button.hot{box-shadow:inset 0 0 0 1px rgba(57,255,106,.35)}

.bottomrow{display:grid;grid-template-columns:1fr 1fr 1.35fr;gap:8px}
/* The same row with one button taken out of it. A target game's bottom row is
   FULL BOARD + UNDO on a number and MISS + UNDO on a ring, never all three, and
   a third empty column reads as a button that failed to draw. */
.bottomrow.two{grid-template-columns:1fr 1.35fr}
.bottomrow.one{grid-template-columns:1fr}
.bottomrow button{
  border-radius:14px;border:1px solid var(--line2);background:var(--surface2);color:var(--ink);
  font-weight:900;font-size:clamp(14px,2.3vh,19px);cursor:pointer;font-family:inherit;
  min-height:clamp(48px,8vh,68px);
  transition:background-color .08s,border-color .08s,color .08s;
}
.bottomrow button:active{transform:scale(.96)}
.bottomrow .undo{background:rgba(255,201,59,.15);border-color:rgba(255,201,59,.42);color:var(--gold)}
.bottomrow .undo:hover{background:rgba(255,201,59,.24)}
.bull{background:rgba(255,59,92,.16)!important;border-color:rgba(255,59,92,.42)!important;color:#FF8098!important}
/* On Bermuda's any-double board the bull is not the red outlier it is in 301,
   it is the best double available - and it sits next to MISS, which is the
   same red and scores nothing. Green says which one you want. */
.bottomrow button.bull.as-target{
  background:linear-gradient(180deg,rgba(57,255,106,.28),rgba(57,255,106,.1))!important;
  border-color:rgba(57,255,106,.6)!important;color:var(--green)!important;
}

/* RTC quick buttons ------------------------------------------------------ */
/* A banner, not a slab. It used to be flex:1 in Round the Clock, which on a
   wide screen grew it to most of the keypad's height for the sake of two
   characters - while Bermuda, which had to leave room for a board underneath,
   had always been compact. Same target, same game, two completely different
   panes. One size now, and it is Bermuda's. */
.target-hero{
  flex:0 0 auto;min-height:0;
  display:grid;place-items:center;align-content:center;background:linear-gradient(150deg,rgba(255,201,59,.14),rgba(255,201,59,.02));
  border:1px solid rgba(255,201,59,.34);border-radius:18px;padding:8px 12px;
}
.target-hero .lbl{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);font-weight:800}
.target-hero .val{font-size:clamp(30px,5.5vh,52px);font-weight:900;letter-spacing:-.05em;line-height:1;color:var(--gold)}
.target-hero .prog{font-size:12px;color:var(--muted);font-weight:700;margin-top:4px}

/* Takes the room the pad has left, and centres the buttons in it.
   It used to be flex:0 0 auto, which pinned the row directly under the banner
   and left the rest of the column empty - about 400px of nothing under the
   keypad on a 1440x900 screen, in every game. align-content rather than a
   stretch, because a row that divides 400px between four buttons gives you
   four 400px buttons, which is not a keypad either. */
.quick{
  flex:1 1 auto;min-height:0;
  display:grid;grid-template-columns:repeat(4,1fr);gap:8px;
  /* Stretch, so the buttons take the room rather than sitting in a 110px
     strip under the banner with 400px of nothing below them - which is what
     flex:0 0 auto gave every game on a 1440x900 screen. Capped, because a row
     that divides the whole column between four buttons gives you four 400px
     buttons, which is not a keypad either. Whatever is left over is split
     above and below by .pad's space-between. */
  align-content:stretch;max-height:clamp(96px,34vh,260px);
}
.quick button{
  /* Grid rather than the button default, so the label stays in the middle
     once the row is allowed to stretch - left to itself it drifted towards
     the bottom of a 260px button. */
  display:grid;place-content:center;
  border-radius:16px;border:1px solid var(--line2);background:var(--surface2);color:var(--ink);
  font-weight:900;font-size:clamp(18px,3.4vh,30px);cursor:pointer;font-family:inherit;
  min-height:clamp(60px,12vh,110px);
  transition:background-color .08s,border-color .08s,color .08s;
}
.quick button:active{transform:scale(.95)}
.quick button.is-target{background:linear-gradient(180deg,rgba(57,255,106,.28),rgba(57,255,106,.1));
  border-color:rgba(57,255,106,.6);color:var(--green)}
.quick button.is-miss{background:rgba(255,59,92,.14);border-color:rgba(255,59,92,.4);color:#FF8098}

/* ---- Killer ------------------------------------------------------------
   The pad asks who you hit, not what. Killer is the only game here where the
   numbers that matter are the players' - four of twenty on a busy night - and
   the scorer already thinks in names. So each tile is a player: their number,
   where their counter stands, and what each ring would leave it on.

   The three results on the rings are not decoration. This game is decided by
   landing exactly, on a counter that bounces off both ends, and the ring that
   does it is marked so nobody has to work it out mid-throw.
   ------------------------------------------------------------------------ */
.quick.killer{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));
  gap:8px;
  /* Eight players wrap to four rows, which on a phone would push MISS and
     UNDO off the bottom - the same trap Bermuda's board fell into. This
     scrolls inside the space it is given, which is safe only because MISS and
     UNDO live outside the box: the worst case is a scroll to reach the eighth
     player, never a miss you cannot record.
     "safe center" so two tiles sit in the middle of a big screen, but an
     overflowing set falls back to the top rather than hiding its first row
     above the scroll. */
  overflow-y:auto;align-content:safe center;
  /* Killer's own height comes from how many players there are, so it is not
     capped the way the four-button row is. */
  max-height:none;
}
.ktile{
  display:flex;flex-direction:column;gap:5px;color:var(--ink);
  border:1px solid var(--line2);background:var(--surface2);
  border-radius:16px;padding:7px 8px 8px;
}
.ktile .hd{display:flex;align-items:baseline;gap:7px;min-width:0}
.ktile .d{font-size:clamp(19px,2.9vh,27px);font-weight:900;letter-spacing:-.03em;line-height:1}
.ktile .nm{
  font-size:11.5px;font-weight:800;color:var(--muted);line-height:1.1;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ktile .hd .k{
  margin-left:auto;flex:0 0 auto;align-self:center;
  font-size:8.5px;font-weight:900;letter-spacing:.1em;
  color:#0B0E12;background:var(--gold);border-radius:999px;padding:1px 5px;
}
.ktile .pips{justify-content:flex-start;margin:0}
.ktile .rings{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;margin-top:auto}
.ktile .rings button{
  display:grid;gap:0;line-height:1.05;padding:5px 0;cursor:pointer;
  border-radius:10px;border:1px solid var(--line);background:rgba(255,255,255,.05);
  color:var(--ink);font-family:inherit;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
}
.ktile .rings button:active{transform:scale(.94)}
.ktile .rings button b{font-size:14px;font-weight:900}
/* What that ring would leave the counter on. Empty when nothing would move -
   promising a number there would be a lie. */
.ktile .rings button i{font-style:normal;font-size:10.5px;font-weight:800;color:var(--dim);min-height:12px}
.ktile .rings button.exact{
  background:linear-gradient(180deg,rgba(57,255,106,.3),rgba(57,255,106,.08));
  border-color:rgba(57,255,106,.65);color:var(--green);
}
.ktile .rings button.exact i{color:var(--green)}
/* Your own tile, wherever it sits in the order. */
.ktile.is-you{box-shadow:inset 0 0 0 2px rgba(255,201,59,.5)}
/* A full counter has nowhere up to go, so every ring of your own number walks
   you backwards. The tile changes sides rather than going quiet. */
.ktile.is-danger{background:rgba(255,59,92,.13);border-color:rgba(255,59,92,.42);color:#FF8098}
.ktile.is-danger .nm{color:#FF8098;opacity:.75}
.ktile.is-out{opacity:.36}
.ktile.is-out .d{text-decoration:line-through}

/* Where the counter stands, as dots rather than a number: four players at
   three each is twelve dots and no arithmetic. */
.pips{display:flex;gap:4px;justify-content:center;margin-top:1px}
.pips i{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.15)}
.pips i.on{background:currentColor;opacity:.92}

/* The banner holds your own number, which is the one target whose meaning
   flips the moment your counter is full. */
.target-hero.armed{
  background:linear-gradient(150deg,rgba(255,59,92,.16),rgba(255,59,92,.03));
  border-color:rgba(255,59,92,.42);
}
.target-hero.armed .lbl,.target-hero.armed .val{color:#FF8098}

.rulelist{margin:6px 0 0;padding-left:16px;font-size:12.5px;line-height:1.5;color:var(--muted)}
.rulelist li{margin-bottom:3px}
.rulelist b{color:var(--ink)}

.rtc-track{display:flex;gap:4px;flex-wrap:wrap;margin-top:6px}
.rtc-track i{
  width:15px;height:15px;border-radius:4px;background:rgba(255,255,255,.09);font-style:normal;
}
.rtc-track i.done{background:var(--green)}
.rtc-track i.now{background:var(--gold);box-shadow:0 0 0 2px rgba(255,201,59,.3)}
/* the bull closes every board and can never be jumped, so it reads as a ring */
.rtc-track i.bull{border-radius:50%;box-shadow:inset 0 0 0 2px rgba(255,255,255,.28)}
.rtc-track i.bull.now{box-shadow:inset 0 0 0 2px rgba(10,14,20,.45),0 0 0 2px rgba(255,201,59,.3)}

/* Bermuda walks named targets, so the track carries labels rather than dots */
.rtc-track.bermuda i{
  width:auto;height:auto;padding:3px 7px;border-radius:6px;font-size:11px;font-weight:800;
  color:var(--dim);background:rgba(255,255,255,.06);line-height:1.3;
}
.rtc-track.bermuda i.done{background:rgba(57,255,106,.16);color:var(--green)}
.rtc-track.bermuda i.now{background:var(--gold);color:#0A0E14;box-shadow:none}

/* the score is about to be halved - make that impossible to miss */
.bigscore.atrisk{
  border-color:rgba(255,59,92,.5);
  background:linear-gradient(160deg,rgba(255,59,92,.16),rgba(255,59,92,.03));
}
.bigscore.atrisk .lbl{color:#FF8098}

/* action sheet (leave / cancel a game) ----------------------------------- */
.sheet{
  position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center;
  background:rgba(0,0,0,.62);padding:16px;
  padding-bottom:calc(16px + env(safe-area-inset-bottom));
}
.sheet-card{
  width:100%;max-width:460px;display:flex;flex-direction:column;gap:10px;
  /* --surface is nearly transparent, which is fine on the page but unreadable
     floating over a live game - the sheet needs a solid ground of its own */
  background:var(--bg2);border:1px solid var(--line2);border-radius:20px;padding:18px;
  box-shadow:0 18px 50px rgba(0,0,0,.6);
  max-height:calc(100dvh - 32px);overflow-y:auto;
}
.sheet-title{font-size:18px;font-weight:900;margin-bottom:2px}
.sheet-card .btn{width:100%;justify-content:center}
.sheet-note{font-size:12.5px;margin:2px 0 0}
@media (min-width:720px){ .sheet{align-items:center} }

/* toast inside the game -------------------------------------------------- */
.gtoast{
  position:fixed;left:50%;top:50%;transform:translate(-50%,-50%) scale(.85);
  padding:20px 44px;border-radius:20px;font-size:clamp(26px,5vw,46px);font-weight:900;letter-spacing:-.02em;
  background:rgba(10,14,20,.93);border:2px solid var(--line2);z-index:120;pointer-events:none;
  opacity:0;transition:opacity .18s,transform .18s;backdrop-filter:blur(14px);text-align:center;
}
.gtoast.show{opacity:1;transform:translate(-50%,-50%) scale(1)}
.gtoast.bust{border-color:var(--red);color:#FF7C94;box-shadow:0 0 60px rgba(255,59,92,.35)}
.gtoast.win{border-color:var(--green);color:var(--green);box-shadow:0 0 70px rgba(57,255,106,.4)}
.gtoast.hit{border-color:var(--gold);color:var(--gold)}
.gtoast .sub{display:block;font-size:15px;font-weight:700;color:var(--muted);margin-top:8px;letter-spacing:0}

@keyframes flashbust{0%,100%{background-color:transparent}25%,75%{background-color:rgba(255,59,92,.14)}}
.game.bustflash{animation:flashbust .5s ease}

/* --------------------------------------------------------------------------
   Phones

   The game screen sizes almost everything in vh, which is right on a tablet in
   landscape but wrong on a phone in both directions:

     portrait   vh is huge, so buttons grow far taller than they are wide and
                their labels ("FULL BOARD", "DOUBLE") overflow the narrow column
     landscape  vh is tiny, so every clamp falls back to its floor and the pad
                no longer fits in the 100dvh grid - the bottom row gets clipped

   On a phone the binding constraint is width, so size by width there, and keep
   the big display text off the floors when the viewport is short.
   -------------------------------------------------------------------------- */
@media (max-width:820px){
  .play{gap:6px}
  .pad,#boardPad{gap:6px}

  /* vmin, not vw or vh: a phone is narrow in portrait and short in landscape,
     and the keypad has to fit whichever axis is the tight one. */
  .mults{gap:6px}
  .mult{
    font-size:clamp(10px,2.9vmin,16px);letter-spacing:.01em;padding:6px 2px;
    min-height:clamp(32px,7vmin,52px);
  }

  .numbers{gap:5px}
  .numbers button{font-size:clamp(13px,5vmin,28px);border-radius:12px}

  .bottomrow{gap:6px;grid-template-columns:1fr 1fr 1.2fr}
  .bottomrow button{
    font-size:clamp(10px,3vmin,17px);min-height:clamp(34px,7.5vmin,58px);
    border-radius:12px;padding:6px 4px;
  }

  .quick{gap:6px}
  .quick button{font-size:clamp(14px,4.6vmin,28px);min-height:clamp(40px,11vmin,90px)}

  /* labels must shrink rather than spill out of their button */
  .mult,.bottomrow button,.quick button{
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }

  .pcard{min-width:104px;padding:7px 10px;gap:8px}
  .pcard .av{--sz:30px}
  .pcard .sc{font-size:clamp(20px,5.5vw,32px)}
  .exitbtn{width:44px;font-size:17px}
  .callerbtn{width:44px}
  .callerbtn svg{width:19px;height:19px}

  .sheet-card .btn-lg{padding:16px 18px;font-size:16px;min-height:56px}
}

/* a phone held sideways: very little height, and the left column has to fit
   its three blocks without their contents colliding */
@media (max-height:520px){
  .bigscore{padding:6px 12px}
  .bigscore .lbl{font-size:9px}
  .bigscore .val{font-size:clamp(24px,7.5vh,56px);margin:1px 0 0}
  .bigscore.rtc .val{font-size:clamp(22px,6.5vh,46px)}
  .bigscore .who{font-size:11px}
  .target-hero{padding:6px}
  .target-hero .val{font-size:clamp(22px,6vh,40px)}
  .target-hero .prog{font-size:10.5px;margin-top:2px}

  .visitbox{padding:7px;gap:4px;overflow:hidden}
  .visitbox .hd{font-size:9px;letter-spacing:.1em}
  .darts{gap:5px}
  .dartslot{min-height:26px;font-size:clamp(12px,3.4vh,19px);border-radius:9px}
  .visitbox .foot .vs{font-size:17px}
  .visitbox .foot .dl{font-size:10.5px}

  .checkout{padding:7px 10px}
  .checkout .lbl{font-size:9px;margin-bottom:3px}
  .checkout .route{font-size:clamp(12px,3.2vh,20px)}
  .checkout .route.alt{font-size:11px}
  .checkout .note{display:none}
  .rtc-track.bermuda i{font-size:9.5px;padding:2px 5px}
  .rtc-track i{width:11px;height:11px}
}

/* portrait: one column, and the left block must not starve the keypad */
@media (orientation:portrait) and (max-width:900px){
  .play{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}
  .leftcol{grid-template-rows:auto auto auto}
  .bigscore{padding:8px 14px}
  .bigscore .val{font-size:clamp(34px,9vw,64px);margin:2px 0 0}
  .bigscore.rtc .val{font-size:clamp(30px,8vw,56px)}
  .dartslot{min-height:36px}
  .visitbox{padding:9px;gap:6px}
  .checkout .note{display:none}
  /* A phone has no room to spare, so the keypad keeps a thumb-sized cap
     rather than the wall-screen one. */
  .quick{max-height:clamp(80px,15vh,130px)}
  /* Width is the scarce axis here, not height, so the banner is sized off it. */
  .target-hero{padding:8px}
  .target-hero .val{font-size:clamp(30px,9vw,58px)}
  .target-hero .prog{font-size:11px}
}

/* Killer's pad is four to eight tiles of three buttons each, so it needs more
   of the screen than any other game's. The rules panel is the first thing to
   go on any phone: the banner already says where your counter stands and what
   it has to reach, and each tile does the arithmetic on its own buttons. */
@media (orientation:portrait) and (max-height:900px){
  .game.killer #killerRules{display:none}
}

/* A small phone in portrait cannot stack five blocks and still leave a usable
   keypad. Bermuda's board list is the first thing to go - the target banner
   already says which target you are on and how many are left. */
@media (orientation:portrait) and (max-height:720px){
  .game.bermuda #rtcProgress{display:none}

  .bigscore{padding:6px 12px}
  .bigscore .val{font-size:clamp(26px,7vw,44px)}
  .visitbox{padding:7px;gap:5px}
  .dartslot{min-height:30px}
  .visitbox .foot .vs{font-size:19px}
  .target-hero .prog{font-size:10px}
}

/* ==========================================================================
   Game setup wizard
   ========================================================================== */
.wizard{max-width:900px;margin:0 auto}
.steps{display:flex;gap:8px;margin-bottom:24px}
.steps .s{flex:1;height:4px;border-radius:2px;background:rgba(255,255,255,.1)}
.steps .s.on{background:var(--green)}

.mode-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
.mode{
  border:1px solid var(--line);border-radius:var(--r-lg);padding:24px 20px;background:var(--surface);
  cursor:pointer;text-align:center;transition:.16s;position:relative;
}
.mode:hover{border-color:var(--line2);background:var(--surface2);transform:translateY(-2px)}
.mode.on{border-color:var(--green);background:rgba(57,255,106,.11);box-shadow:0 0 0 1px rgba(57,255,106,.25)}
.mode .big{font-size:clamp(30px,4vw,42px);font-weight:900;letter-spacing:-.04em}
.mode .sm{color:var(--muted);font-size:13px;margin-top:6px}
.mode.on .big{color:var(--green)}

.pick-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:10px}
.pick{
  display:flex;align-items:center;gap:12px;padding:13px 15px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);cursor:pointer;transition:.14s;position:relative;
}
.pick:hover{background:var(--surface2)}
.pick.on{border-color:var(--green);background:rgba(57,255,106,.1)}
.pick .nm{font-weight:800;font-size:16px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pick .ord{
  width:28px;height:28px;border-radius:50%;background:var(--green);color:#06140B;
  display:grid;place-items:center;font-weight:900;font-size:14px;flex:none;
}
.pick:not(.on) .ord{display:none}

.order-list{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.order-item{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:var(--r-sm);
  background:var(--surface);border:1px solid var(--line)}
.order-item .idx{width:26px;height:26px;border-radius:50%;background:var(--surface2);display:grid;place-items:center;
  font-weight:900;font-size:13px;color:var(--muted);flex:none}
.order-item .nm{flex:1;font-weight:800}
.order-item button{width:38px;height:38px;border-radius:9px;border:1px solid var(--line2);
  background:var(--surface2);color:var(--ink);font-weight:900;cursor:pointer;font-size:16px}

/* ==========================================================================
   Winner screen
   ========================================================================== */
.winner-hero{text-align:center;padding:34px 0 26px}
.winner-hero .crown{font-size:56px;margin-bottom:6px}
.winner-hero .lbl{letter-spacing:.32em;font-size:12px;color:var(--gold);font-weight:800}
.winner-hero h1{font-size:clamp(42px,8vw,84px);margin-top:6px;
  background:linear-gradient(94deg,var(--gold),var(--green));-webkit-background-clip:text;background-clip:text;color:transparent}
.winner-hero .av{margin:16px auto 0;box-shadow:0 0 0 4px rgba(255,201,59,.35),0 20px 50px rgba(0,0,0,.5)}

.result-row{
  display:flex;align-items:center;gap:14px;padding:14px 16px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);margin-bottom:9px;flex-wrap:wrap;
}
.result-row.win{border-color:rgba(255,201,59,.45);background:rgba(255,201,59,.07)}
.result-row .nm{font-weight:900;font-size:18px;min-width:130px}
.result-row .mini{display:flex;gap:18px;flex-wrap:wrap;margin-left:auto}
.result-row .mini div{text-align:right}
.result-row .mini .k{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:800}
.result-row .mini .v{font-size:19px;font-weight:900}

/* ==========================================================================
   Stats page
   ========================================================================== */
.filters{
  display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;padding:16px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);margin-bottom:22px;
}
.filters > div{flex:1;min-width:150px}
.section{margin-top:34px}
.section > h2{margin-bottom:14px;display:flex;align-items:center;gap:12px}
.section > h2::after{content:"";flex:1;height:1px;background:var(--line)}

.chart-box{position:relative;height:280px}
.chart-box.tall{height:340px}

/* Thirty slim columns, one per day, on the admin dashboard. Each bar's height
   is its share of the busiest day rather than an absolute count: the shape is
   the point, and an axis small enough to fit a phone is an axis nobody reads.
   A day with nothing thrown keeps a visible stub, so a gap reads as a quiet
   day rather than as a chart that stopped early. */
.spark{display:flex;align-items:flex-end;gap:3px;height:92px;padding:2px 0}
.spark .sbar{
  flex:1 1 0;min-width:3px;border-radius:3px 3px 0 0;
  height:max(3px,var(--h));
  background:linear-gradient(180deg,var(--green),var(--blue));
}
.spark .sbar.zero{height:3px;background:var(--line2)}
.spark-axis{display:flex;align-items:center;margin-top:6px}

.heat-board{display:grid;grid-template-columns:repeat(auto-fill,minmax(74px,1fr));gap:7px}
.heat-cell{
  border-radius:12px;padding:10px 8px;text-align:center;border:1px solid var(--line);
  background:rgba(57,255,106,calc(var(--i) * .55));
}
.heat-cell .n{font-size:19px;font-weight:900;letter-spacing:-.02em}
.heat-cell .h{font-size:11px;color:var(--muted);font-weight:700;margin-top:2px}
.heat-cell .p{font-size:10.5px;color:var(--dim);font-weight:700}

.empty-state{text-align:center;padding:60px 20px;color:var(--muted)}
.empty-state .big{font-size:46px;margin-bottom:12px;opacity:.5}

/* practice cards --------------------------------------------------------- */
.rec{
  display:flex;gap:16px;padding:18px;border-radius:var(--r);background:var(--surface);
  border:1px solid var(--line);margin-bottom:11px;align-items:flex-start;
}
.rec .rank{
  width:42px;height:42px;border-radius:12px;display:grid;place-items:center;flex:none;
  font-weight:900;font-size:18px;background:rgba(57,255,106,.14);color:var(--green);border:1px solid rgba(57,255,106,.3);
}
.rec.p2 .rank{background:rgba(255,201,59,.14);color:var(--gold);border-color:rgba(255,201,59,.3)}
.rec.p3 .rank{background:rgba(59,200,255,.14);color:var(--blue);border-color:rgba(59,200,255,.3)}
.rec .body{flex:1;min-width:0}
.rec .ttl{font-weight:900;font-size:19px;letter-spacing:-.02em}
.rec .why{color:var(--muted);font-size:14px;margin-top:5px;line-height:1.55}
.rec .drill{font-size:13px;margin-top:9px;color:var(--green);font-weight:700}
.rec .score{text-align:right;flex:none}
.rec .score .v{font-size:24px;font-weight:900}
.rec .score .k{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:800}

.delta{font-weight:900;font-size:15px}
.delta.up{color:var(--green)}
.delta.down{color:var(--red)}

/* replay ----------------------------------------------------------------- */
.replay-visit{
  display:flex;align-items:center;gap:12px;padding:10px 14px;border-radius:12px;
  background:var(--surface);border:1px solid var(--line);margin-bottom:6px;flex-wrap:wrap;
}
.replay-visit.bust{border-color:rgba(255,59,92,.35);background:rgba(255,59,92,.06)}
.replay-visit.checkout{border-color:rgba(255,201,59,.45);background:rgba(255,201,59,.08)}
.replay-visit .who{font-weight:800;min-width:96px;font-size:14px}
.replay-visit .prog{font-family:var(--mono);font-size:13px;color:var(--muted);min-width:110px}
.replay-visit .dl{display:flex;gap:6px;flex-wrap:wrap}
.replay-visit .dl span{
  padding:4px 10px;border-radius:8px;background:rgba(255,255,255,.07);font-weight:800;font-size:13px;
  border:1px solid var(--line);
}
.replay-visit .dl span.miss{color:var(--dim)}
.replay-visit .dl span.co{border-color:rgba(255,201,59,.4);color:var(--gold)}
.replay-visit .dl span.on{border-color:rgba(57,255,106,.45);color:var(--green)}
.replay-visit .tot{margin-left:auto;font-weight:900;font-size:18px}

/* error page ------------------------------------------------------------- */
.errpage{text-align:center;padding:80px 20px}
.errpage .code{font-size:96px;font-weight:900;letter-spacing:-.05em;color:var(--red);opacity:.8}

/* misc ------------------------------------------------------------------- */
.muted{color:var(--muted)}
.dim{color:var(--dim)}
.center{text-align:center}
.mt{margin-top:16px}
.mt-lg{margin-top:28px}
.mb{margin-bottom:16px}
.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.nowrap{white-space:nowrap}
hr.sep{border:0;border-top:1px solid var(--line);margin:24px 0}

/* ==========================================================================
   Who throws first: coin flip + bull-up
   ========================================================================== */
.coin{
  width:110px;height:110px;margin:6px auto 14px;border-radius:50%;
  display:grid;place-items:center;font-size:52px;
  background:radial-gradient(circle at 34% 30%,#FFE9A8,#E0A93B 62%,#9C6F19);
  box-shadow:0 12px 30px rgba(0,0,0,.5),inset 0 -5px 14px rgba(0,0,0,.28);
}
.coin.spin{animation:coinflip .9s cubic-bezier(.3,.7,.3,1)}
@keyframes coinflip{
  0%{transform:rotateY(0) translateY(0)}
  50%{transform:rotateY(900deg) translateY(-56px)}
  100%{transform:rotateY(1800deg) translateY(0)}
}
.coin-result{font-size:20px;font-weight:800;letter-spacing:-.02em;min-height:26px}
.coin-result b{color:var(--green)}

.bull-who{font-size:clamp(28px,5vw,42px);font-weight:900;letter-spacing:-.03em;color:var(--green)}
#bullTieList .pick{cursor:pointer}

/* leg / set score on the live scoreboard --------------------------------- */
.pcard .ls{
  display:flex;gap:5px;align-items:center;margin-top:3px;
}
.pcard .ls span{
  padding:1px 7px;border-radius:6px;font-size:10.5px;font-weight:800;letter-spacing:.04em;
  background:rgba(255,255,255,.08);border:1px solid var(--line);color:var(--muted);
}
.pcard.active .ls span{background:rgba(57,255,106,.14);border-color:rgba(57,255,106,.3);color:var(--green)}
.pcard .ls span.sets{background:rgba(255,201,59,.14);border-color:rgba(255,201,59,.32);color:var(--gold)}

.legbadge{
  position:absolute;top:6px;right:9px;font-size:10px;font-weight:800;letter-spacing:.1em;
  color:var(--dim);text-transform:uppercase;
}

/* match standings --------------------------------------------------------- */
.standing{
  display:flex;align-items:center;gap:14px;padding:14px 18px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);margin-bottom:9px;
}
.standing.lead{border-color:rgba(255,201,59,.45);background:rgba(255,201,59,.07)}
.standing .nm{font-weight:900;font-size:19px;flex:1;min-width:0}
.standing .big-num{font-size:clamp(30px,5vw,44px);font-weight:900;letter-spacing:-.04em;line-height:1}
.standing .unit{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800;text-align:center}
.standing .col{text-align:center;min-width:64px}

.leg-row{
  display:flex;align-items:center;gap:14px;padding:12px 16px;border-radius:12px;
  background:var(--surface);border:1px solid var(--line);margin-bottom:7px;flex-wrap:wrap;
}
.leg-row .lg{font-weight:800;min-width:104px;font-size:14px}
.leg-row .who{font-weight:800;color:var(--gold)}
.leg-row .mini{display:flex;gap:16px;margin-left:auto;flex-wrap:wrap}
.leg-row .mini div{text-align:right}
.leg-row .mini .k{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:800}
.leg-row .mini .v{font-size:17px;font-weight:900}

.quick button{position:relative}
.quick button .jump{
  position:absolute;top:7px;right:10px;font-size:12px;font-weight:900;
  color:var(--gold);letter-spacing:0;opacity:.9;
}
.quick button.is-target .jump{color:var(--green)}

/* ==========================================================================
   Accounts, friends and guests
   ========================================================================== */
.authwrap{max-width:460px;margin:0 auto;padding:clamp(24px,6vh,64px) 4px 60px}
.authwrap h1{font-size:clamp(30px,5vw,42px);margin-bottom:6px}
.authbrand{display:flex;align-items:center;gap:11px;justify-content:center;margin-bottom:26px;
  font-weight:900;letter-spacing:.2em;font-size:14px}
.authbrand .brand-mark{width:34px;height:34px}
.authbrand span{background:linear-gradient(92deg,var(--green),var(--blue));
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* ==========================================================================
   Levels, countries and the global board
   ========================================================================== */

/* Two boards, one page-head: which one you are on has to be obvious. */
.scopetabs{display:inline-flex;gap:2px;padding:3px;border-radius:999px;
  background:var(--surface2);border:1px solid var(--line)}
.scopetabs a{padding:7px 15px;border-radius:999px;font-weight:800;font-size:13px;
  color:var(--muted);white-space:nowrap}
.scopetabs a.on{background:var(--surface);color:var(--ink);
  box-shadow:0 1px 3px rgba(0,0,0,.4)}

/* A country as two letters. No flag emoji: see services/countries.py. */
.cc{display:inline-block;padding:1px 6px;border-radius:5px;background:var(--surface2);
  border:1px solid var(--line);color:var(--muted);font-size:10.5px;font-weight:900;
  letter-spacing:.09em;vertical-align:1px}

/* The rank names. Each tier is a material, and reads like one. */
.lvl{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;
  font-weight:900;letter-spacing:.02em;white-space:nowrap;
  border:1px solid var(--tint,var(--line));color:var(--tone,var(--muted));
  background:color-mix(in srgb, var(--tone,var(--muted)) 12%, transparent)}
/* The level rides under the name only where its own column is hidden,
   otherwise every row says it twice. */
.note.lvl-sm{font-weight:800;color:var(--tone,var(--muted))}
@media (min-width:641px){ .note.lvl-sm{display:none} }

.lvl-unranked{--tone:#6C7A8A;--tint:rgba(108,122,138,.35)}
.lvl-stone   {--tone:#8B96A3;--tint:rgba(139,150,163,.35)}
.lvl-copper  {--tone:#C87F4A;--tint:rgba(200,127,74,.40)}
.lvl-iron    {--tone:#9AA6B2;--tint:rgba(154,166,178,.40)}
.lvl-bronze  {--tone:#CD7F32;--tint:rgba(205,127,50,.45)}
.lvl-silver  {--tone:#C6D2DE;--tint:rgba(198,210,222,.45)}
.lvl-gold    {--tone:#FFC93B;--tint:rgba(255,201,59,.45)}
.lvl-platinum{--tone:#93BEE8;--tint:rgba(147,190,232,.45)}
.lvl-diamond {--tone:#7BE7E0;--tint:rgba(123,231,224,.45)}
.lvl-master  {--tone:#B96BFF;--tint:rgba(185,107,255,.45)}
.lvl-legend  {--tone:#FF5FD2;--tint:rgba(255,95,210,.50)}

.ladder{display:flex;flex-direction:column;gap:2px;margin-top:12px}
.rung{display:grid;grid-template-columns:170px 54px 1fr;align-items:center;gap:12px;
  padding:7px 10px;border-radius:8px}
.rung:nth-child(odd){background:var(--surface2)}
@media (max-width:640px){
  .rung{grid-template-columns:1fr auto;row-gap:2px}
  .rung .muted{grid-column:1 / -1}
}

.joinbar{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:18px;
  border-color:rgba(57,255,106,.28)}

/* a checkbox with room to explain itself */
.switchrow{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;
  border-radius:10px;background:var(--surface2);cursor:pointer}
.switchrow input{width:22px;height:22px;flex:none;margin-top:1px;
  position:static;opacity:1}
.switchrow b{display:block;color:var(--ink)}
.switchrow small{display:block;line-height:1.45;margin-top:2px}
.rank-table.world td .who .nm a{color:var(--ink)}
.rank-table.world td .who .nm a:hover{color:var(--green)}
.rank-table.world td form{margin:0}

.only-sm{display:none}
@media (max-width:640px){
  /* The board has to fit a phone without sideways scrolling, or the Add
     friend button sits off the edge where nobody will ever find it. */
  .only-sm{display:inline}
  .rank-table.world th,
  .rank-table.world td{padding-left:7px;padding-right:7px}
  .rank-table.world .who{gap:9px}
  .rank-table.world .nm{font-size:14px}
  .rank-table.world .val{font-size:15px}
  .rank-table.world td:last-child .btn{padding:7px 10px;font-size:12.5px}
}

/* ==========================================================================
   Footer and the legal pages
   ========================================================================== */
.sitefoot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;justify-content:center;
  padding:26px clamp(16px,3vw,32px) 40px;border-top:1px solid var(--line);
  margin-top:40px;font-size:13px;position:relative;z-index:1}
.sitefoot nav{display:flex;gap:4px;flex-wrap:wrap;justify-content:center}
.sitefoot a{padding:6px 11px;border-radius:999px;color:var(--muted);font-weight:700}
.sitefoot a:hover{color:var(--ink);background:var(--surface)}

/* The honeypot. Off-screen rather than display:none, because some bots skip
   anything a stylesheet has hidden outright. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* Long-form text wants a narrower measure than a stats table does. */
.prose{max-width:74ch}
.prose h2{font-size:19px;margin:30px 0 10px;color:var(--ink);
  text-transform:none;letter-spacing:0}
.prose h3{font-size:15px;margin:20px 0 6px;color:var(--ink);
  text-transform:none;letter-spacing:0}
.prose p,.prose li{color:var(--muted);line-height:1.68;font-size:14.5px}
.prose p{margin:0 0 12px}
.prose ul{margin:0 0 14px;padding-left:20px}
.prose li{margin-bottom:5px}
.prose li::marker{color:var(--dim)}
.prose strong{color:var(--ink)}
.prose a{color:var(--green);text-decoration:underline;text-underline-offset:3px}
.prose .updated{color:var(--dim);font-size:12.5px}
/* min-width:0 undoes the global table{min-width:480px}, which exists for the
   wide stats tables that live inside a horizontal scroller. A table of prose
   has no scroller and must simply fit the phone. */
.prose table{width:100%;min-width:0;border-collapse:collapse;margin:6px 0 18px;
  font-size:13.5px}
.prose th,.prose td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--line);
  color:var(--muted);vertical-align:top}
.prose th{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.1em;
  font-weight:800}
.prose td:first-child{color:var(--ink);font-weight:700;white-space:nowrap}
/* A two- or three-column table of prose does not fit a phone and cannot be
   usefully scrolled sideways either, so below 640px each row becomes a small
   stacked block. The header row is dropped and each cell carries its own
   label instead. */
@media (max-width:640px){
  .prose table,.prose tbody,.prose tr,.prose td{display:block;width:100%}
  .prose thead{display:none}
  .prose tr{padding:12px 0;border-bottom:1px solid var(--line)}
  .prose td{border:0;padding:0}
  /* first-child, explicitly: the nowrap above is more specific than a bare
     `.prose td`, and a nowrap block simply grows past its parent */
  .prose td,.prose td:first-child{white-space:normal}
  .prose td:first-child{font-size:14.5px;margin-bottom:3px}
  .prose td[data-label]::before{
    content:attr(data-label);display:block;margin-top:7px;
    color:var(--dim);font-size:10.5px;font-weight:800;
    text-transform:uppercase;letter-spacing:.1em;
  }
}

/* a button that has to sit in a sentence: same weight as the links beside it */
.linky{background:none;border:0;padding:0;font:inherit;color:var(--muted);
  font-weight:800;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.linky:hover{color:var(--ink)}

/* the state of an email address, said in one line */
.emstate{display:flex;align-items:center;gap:9px;padding:11px 13px;border-radius:var(--r-sm);
  background:var(--surface2);font-size:13.5px;line-height:1.35}
.emstate .tick{flex:none;width:9px;height:9px;border-radius:50%;background:var(--green)}
.emstate.wait .tick{background:var(--gold)}
.emstate.none .tick{background:var(--red)}
.emstate b{color:var(--ink);word-break:break-all}

.claim-list{display:flex;flex-direction:column;gap:8px;margin-top:10px}
.claim{display:flex;align-items:center;gap:12px;padding:13px 15px;border-radius:var(--r-sm);
  background:rgba(0,0,0,.25);border:1px solid var(--line);cursor:pointer;transition:.14s}
.claim:hover{border-color:var(--line2)}
.claim input{width:20px;height:20px;flex:none;accent-color:var(--green)}
.claim span{display:flex;flex-direction:column;gap:2px}
.claim b{font-size:15px}
.claim small{color:var(--muted);font-size:12.5px}
.claim:has(input:checked){border-color:var(--green);background:rgba(57,255,106,.08)}

.friend-row{display:flex;align-items:center;gap:13px;padding:13px 16px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line);margin-bottom:8px;flex-wrap:wrap}
.friend-row .av{flex:none}

.badge{display:inline-block;min-width:18px;padding:1px 6px;border-radius:999px;
  background:var(--gold);color:#1a1204;font-size:11px;font-weight:900;text-align:center;margin-left:2px}

.topnav a.navme{display:flex;align-items:center;gap:8px;max-width:190px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.topnav a.navme img{width:24px;height:24px;border-radius:50%;object-fit:cover;flex:none}

.pick .pill{flex:none}

/* Double In on the game screen ------------------------------------------- */
.bigscore.notin .val{color:var(--gold);opacity:.85}
.bigscore.notin .lbl{color:var(--gold)}
.checkout.doublein{background:linear-gradient(135deg,rgba(59,200,255,.16),rgba(59,200,255,.04));
  border-color:rgba(59,200,255,.4)}
.checkout.doublein .lbl{color:var(--blue)}
.checkout.doublein .route{color:var(--blue)}
.pcard .notin-flag{font-size:10px;font-weight:900;color:var(--gold);letter-spacing:.08em}

/* ==========================================================================
   Camera auto-scoring (BETA)
   ========================================================================== */
.beta{
  display:inline-block;padding:2px 8px;border-radius:6px;vertical-align:middle;
  font-size:10px;font-weight:900;letter-spacing:.14em;
  background:rgba(255,201,59,.16);border:1px solid rgba(255,201,59,.45);color:var(--gold);
  margin-left:8px;
}
.beta-notice{
  padding:16px 18px;border-radius:var(--r);line-height:1.6;font-size:14px;
  background:linear-gradient(135deg,rgba(255,201,59,.10),rgba(255,201,59,.02));
  border:1px solid rgba(255,201,59,.3);color:var(--ink);
}
.beta-notice b{color:var(--gold)}

.cam-card .cam-name{font-weight:800;font-size:17px}
.cam-preview{
  position:relative;aspect-ratio:16/9;border-radius:12px;overflow:hidden;
  background:#05080c;border:1px solid var(--line);display:grid;place-items:center;
}
.cam-preview img{width:100%;height:100%;object-fit:contain;display:block}
.cam-placeholder{color:var(--dim);font-size:13px;font-weight:700}
.cam-quality{font-size:12.5px;margin-top:8px;min-height:18px}
.cam-status{font-size:13.5px;color:var(--muted)}
.cam-status .dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:8px}
.cam-status .dot.ok{background:var(--green)}
.cam-status .dot.bad{background:var(--red)}

/* calibration ------------------------------------------------------------ */
.calib-layout{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(280px,1fr);gap:18px}
@media (max-width:900px){.calib-layout{grid-template-columns:1fr}}
.calib-stage{
  position:relative;border-radius:var(--r);overflow:hidden;background:#05080c;
  border:1px solid var(--line2);min-height:240px;cursor:crosshair;
}
.calib-stage img{width:100%;display:none}
.calib-stage svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.calib-empty{position:absolute;inset:0;display:grid;place-items:center;color:var(--dim);font-size:13px}

.calib-points{list-style:none;margin:0;padding:0;counter-reset:pt}
.calib-points li{
  display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:10px;
  border:1px solid var(--line);margin-bottom:6px;cursor:pointer;transition:.14s;
}
.calib-points li.on{border-color:var(--gold);background:rgba(255,201,59,.08)}
.calib-points li.done .pt-dot{background:var(--green);border-color:var(--green)}
.calib-points .pt-dot{
  width:14px;height:14px;border-radius:50%;border:2px solid var(--line2);flex:none;
}
.calib-points .pt-body{flex:1;min-width:0;display:flex;flex-direction:column}
.calib-points .pt-body b{font-size:14px}
.calib-points .pt-body small{font-size:11.5px}
.calib-points .pt-coord{font-size:11px;font-family:var(--mono)}

.calib-good{padding:12px 14px;border-radius:10px;background:rgba(57,255,106,.1);
  border:1px solid rgba(57,255,106,.35);font-size:13.5px;line-height:1.55}
.calib-bad{padding:12px 14px;border-radius:10px;background:rgba(255,59,92,.1);
  border:1px solid rgba(255,59,92,.35);font-size:13.5px;color:#FF8098}
.calib-test{padding:14px;border-radius:10px;background:rgba(0,0,0,.25);
  border:1px solid var(--line);min-height:52px;display:flex;align-items:center;gap:10px}
.calib-score{font-size:26px;font-weight:900;letter-spacing:-.02em;color:var(--green)}

/* detections ------------------------------------------------------------- */
.detect-card{
  padding:14px 16px;border-radius:var(--r);border:1px solid var(--line);
  background:var(--surface);margin-bottom:8px;
}
.detect-card.high{border-color:rgba(57,255,106,.4)}
.detect-card.medium{border-color:rgba(255,201,59,.45)}
.detect-card.low{border-color:rgba(255,59,92,.4)}
.detect-main{display:flex;align-items:baseline;gap:14px}
.detect-label{font-size:30px;font-weight:900;letter-spacing:-.03em}
.detect-conf{font-size:16px;font-weight:800;color:var(--muted);margin-left:auto}
.detect-meta{font-size:12px;margin-top:4px}
.obs-list{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.obs{display:flex;gap:8px;align-items:center;padding:5px 10px;border-radius:8px;
  background:rgba(255,255,255,.05);border:1px solid var(--line);font-size:12px}
.obs b{font-size:13px}

/* on the game screen ----------------------------------------------------- */
.cambar{
  display:flex;align-items:center;gap:10px;padding:7px 12px;border-radius:12px;
  background:rgba(255,201,59,.08);border:1px solid rgba(255,201,59,.28);
  font-size:12.5px;font-weight:700;color:var(--gold);flex-wrap:wrap;
}
.cambar .dot{width:9px;height:9px;border-radius:50%;background:var(--green);flex:none}
.cambar .dot.bad{background:var(--red)}
.cambar .dot.warn{background:var(--gold)}
.cambar .spacer{flex:1}
.cambar button{
  padding:5px 12px;border-radius:8px;border:1px solid var(--line2);
  background:var(--surface2);color:var(--ink);font-weight:800;font-size:12px;cursor:pointer;
}

.camprompt{
  position:fixed;left:50%;bottom:22px;transform:translateX(-50%);
  z-index:130;padding:16px 20px;border-radius:16px;min-width:min(440px,92vw);
  background:rgba(10,14,20,.97);border:2px solid var(--gold);box-shadow:var(--shadow);
  backdrop-filter:blur(14px);
}
.camprompt .q{font-size:13px;color:var(--muted);font-weight:700;margin-bottom:6px}
.camprompt .big{font-size:34px;font-weight:900;letter-spacing:-.03em;color:var(--gold)}
.camprompt .row{margin-top:12px;gap:8px}
.camprompt button{flex:1;padding:12px;border-radius:10px;font-weight:900;font-size:14px;
  border:1px solid var(--line2);background:var(--surface2);color:var(--ink);cursor:pointer}
.camprompt button.yes{background:linear-gradient(180deg,#4BFF7C,#22D954);color:#05130A;border-color:transparent}
.camprompt button.no{background:rgba(255,59,92,.16);border-color:rgba(255,59,92,.4);color:#FF8098}

.dartslot.camera{border-color:rgba(255,201,59,.5);background:rgba(255,201,59,.1)}
.dartslot .cam-tag{
  position:absolute;top:3px;right:5px;font-size:9px;font-weight:900;color:var(--gold);
  letter-spacing:.06em;
}
.dartslot{position:relative}

/* streaming a camera from another device --------------------------------- */
.cam-preview video{width:100%;height:100%;object-fit:contain;display:none;background:#05080c}
.stream-stat{
  font-size:14px;font-weight:700;padding:12px 14px;border-radius:10px;
  background:rgba(0,0,0,.25);border:1px solid var(--line);
}
.stream-stat .dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:9px}
.stream-stat .dot.ok{background:var(--green)}
.stream-stat .dot.bad{background:var(--red)}
.stream-stat .dot.warn{background:var(--gold)}

.mode.disabled{opacity:.45;cursor:not-allowed}
.mode.disabled:hover{transform:none;border-color:var(--line);background:var(--surface)}

/* rotating the board overlay during automatic calibration ---------------- */
.rotate-row{display:flex;align-items:center;gap:12px}
.rotate-row .btn{flex:0 0 auto;min-width:64px;font-size:20px;padding:12px 16px}
.rotate-read{flex:1;text-align:center;padding:10px;border-radius:10px;
  background:rgba(0,0,0,.25);border:1px solid var(--line)}
.rotate-read b{display:block;font-size:24px;font-weight:900;letter-spacing:-.02em}
.rotate-read small{font-size:11px;letter-spacing:.1em;text-transform:uppercase}

/* ==========================================================================
   COMPARE - several players, many characteristics, side by side
   ========================================================================== */
.sm{font-size:12.5px}
.page-head.tight{margin-bottom:14px}

/* ---- setup panel: plain dropdowns, nothing clever ----------------------- */
.setup{
  padding:14px;border-radius:var(--r);margin-bottom:20px;
  background:var(--surface);border:1px solid var(--line);
}
.setup-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.setup-row + .setup-row{margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.setup .fld{flex:0 1 172px;min-width:146px;display:block;margin:0}
.setup .fld.grow{flex:1 1 260px}
.setup .fld.shrink{flex:0 0 auto;min-width:0}
.setup .fl{display:block;margin-bottom:6px}
.setup select,.setup input[type=text],.setup input[type=date]{margin:0;width:100%}
/* long names must not be clipped by the select box */
.setup select{text-overflow:ellipsis}
.setup .saveline .muted{flex:1 1 100%;margin:0}
.setup button[disabled]{opacity:.45;cursor:not-allowed}

/* ---- who is in ---------------------------------------------------------- */
.lineup{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:16px}
.lu{
  display:inline-flex;align-items:center;gap:8px;padding:6px 13px 6px 6px;
  border-radius:999px;background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--who);
}
.lu .av{--sz:26px;border-width:1px}
.lu .n{font-weight:800;font-size:13px;color:var(--ink)}
.lu .g{font-size:11px;color:var(--dim)}

/* ---- who leads what ----------------------------------------------------- */
.leaders{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  gap:11px;margin-bottom:20px;
}
.lead{
  position:relative;padding:14px 15px;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--line);background:var(--surface);
}
.lead::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;background:var(--who)}
.lead .k{font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--dim)}
.lead .v{font-size:27px;font-weight:900;letter-spacing:-.03em;color:var(--who);margin:5px 0 7px;line-height:1}
.lead .v small{font-size:14px;margin-left:1px;opacity:.75}
.lead .who{display:flex;align-items:center;gap:7px;font-weight:800;font-size:12.5px;color:var(--muted)}
.lead .who .av{--sz:24px;border-width:1px}

/* ---- collapsible metric groups ------------------------------------------ */
.mgroup{margin-top:20px;border-radius:var(--r);border:1px solid var(--line);background:var(--surface);overflow:hidden}
.mgroup > summary{
  display:flex;align-items:center;gap:11px;padding:15px 17px;cursor:pointer;
  list-style:none;transition:.14s;
}
.mgroup > summary::-webkit-details-marker{display:none}
.mgroup > summary::after{
  content:"\2304";margin-left:auto;font-size:17px;color:var(--muted);
  transition:transform .18s;line-height:1;
}
.mgroup[open] > summary::after{transform:rotate(180deg)}
.mgroup > summary:hover{background:var(--surface2)}
.mgroup .gt{font-size:17px;font-weight:900;letter-spacing:-.02em}
.mgroup .gs{font-size:12.5px;color:var(--dim)}
.mgroup .gn{
  font-size:11px;font-weight:800;color:var(--muted);padding:2px 8px;
  border-radius:999px;background:var(--surface2);border:1px solid var(--line);
}
.mgroup .tbl-wrap{border:0;border-top:1px solid var(--line);border-radius:0}

/* ---- the tables --------------------------------------------------------- */
.cmp-table{min-width:520px}
.cmp-table th.r,.cmp-table td.r{text-align:right}
.cmp-table thead th{vertical-align:bottom;border-bottom:2px solid var(--who,var(--line))}
.cmp-table thead th.metric{border-bottom:2px solid var(--line)}
.cmp-table thead th .av{--sz:26px;border-width:1px;margin-left:auto;display:block;margin-bottom:5px}
.cmp-table thead th .hn{
  display:block;max-width:96px;margin-left:auto;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--who);
}
/* the metric name stays put while the player columns scroll sideways */
.cmp-table td.metric,.cmp-table th.metric{
  position:sticky;left:0;z-index:1;background:#0D131B;min-width:172px;
}
.cmp-table tbody tr:nth-child(even) td.metric{background:#0F1620}
.cmp-table tbody tr:nth-child(even) td{background:rgba(255,255,255,.012)}
.cmp-table .metric .lbl{font-weight:800;font-size:13.5px;color:var(--ink)}
.cmp-table .metric .hint{font-size:11px;color:var(--dim);margin-top:2px;line-height:1.35}
.cmp-table .metric .lower{color:var(--blue);font-size:9.5px;margin-left:3px}
.cmp-table .val{font-size:17px;font-weight:900;letter-spacing:-.02em;white-space:nowrap}
.cmp-table .val small{font-size:11px;color:var(--muted);margin-left:1px}
.cmp-table .val.dim{color:var(--dim)}
.cmp-table td .sub{font-size:10.5px;color:var(--dim);margin-top:2px}
.cmp-table td .bar{margin-top:7px;margin-left:auto;max-width:104px;min-width:40px;height:6px}
.cmp-table td.best{background:rgba(57,255,106,.06) !important}
.cmp-table td.best .val{color:var(--green)}
.cmp-table .crown{color:var(--gold);font-size:11px;margin-left:4px}
/* a row everybody drew is information, but it is not a contest */
.cmp-table tr.drawn .val{color:var(--muted)}
.cmp-table tr.drawn .bar{opacity:.4}

/* ---- head to head ------------------------------------------------------- */
.h2h{
  display:flex;align-items:center;gap:12px;padding:12px;border-radius:14px;
  border:1px solid var(--line);background:rgba(0,0,0,.2);margin-top:10px;
}
.h2h.win{border-color:rgba(57,255,106,.3);background:rgba(57,255,106,.06)}
.h2h.level{border-color:rgba(255,201,59,.3);background:rgba(255,201,59,.06)}
.h2h .who{flex:1;min-width:0}
.h2h .who .nm{font-weight:800;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.h2h .who .sub{font-size:11.5px;color:var(--dim)}
.h2h .score{font-size:23px;font-weight:900;letter-spacing:-.02em;white-space:nowrap}
.h2h .score .mine{color:var(--green)}
.h2h .score .sep{color:var(--dim);margin:0 3px}
.h2h .score .theirs{color:var(--red)}
.h2h .pct{font-size:12px;color:var(--muted);min-width:46px;text-align:right}
.h2h .pct small{font-size:9px}

.nodata{text-align:center;padding:34px 14px}
.nodata .big{font-size:34px;opacity:.35;margin-bottom:10px}
.nodata p{max-width:330px;margin:0 auto}

@media (max-width:640px){
  .setup .fld{flex:1 1 100%;min-width:0}
  .setup .fld.shrink{flex:0 0 auto}
  .leaders{grid-template-columns:repeat(auto-fit,minmax(134px,1fr));gap:9px}
  .lead .v{font-size:22px}
  .cmp-table{min-width:440px}
  .cmp-table td.metric,.cmp-table th.metric{min-width:136px}
  .cmp-table td .bar{max-width:64px}
  .mgroup .gs{display:none}
}


/* ==========================================================================
   ACHIEVEMENTS  (.ach, not .badge - that one is the nav notification pill)
   ========================================================================== */

/* Tier metals: --t1 is the body of the metal, --t2 its shadow, --tg the
   polished highlight. One place, used by the hero pills, the ribbons, the
   showcase and every tile. */
.bronze  { --t1:#C77F3C; --t2:#5F3111; --tg:#FFDCB0 }
.silver  { --t1:#BEC5CD; --t2:#575E68; --tg:#FBFCFD }
.gold    { --t1:#E5B62E; --t2:#7C5205; --tg:#FFF4C6 }
/* platinum has to be unmistakable next to silver, or the top tier looks like
   the one below it - so it takes a cold blue cast rather than neutral grey */
.platinum{ --t1:#93BEE8; --t2:#26456B; --tg:#F2F9FF }

/* ---- hero --------------------------------------------------------------- */
.trophy-hero{
  display:flex;gap:24px;align-items:center;flex-wrap:wrap;
  padding:24px;border-radius:var(--r-lg);margin-bottom:18px;position:relative;overflow:hidden;
  background:
    radial-gradient(120% 150% at 0% 0%, rgba(57,255,106,.10), transparent 60%),
    radial-gradient(120% 150% at 100% 100%, rgba(255,201,59,.09), transparent 60%),
    var(--surface);
  border:1px solid var(--line);
}
.trophy-hero .tring{
  flex:0 0 auto;width:132px;height:132px;border-radius:50%;display:grid;place-items:center;
  background:conic-gradient(var(--green) calc(var(--pct) * 1%), rgba(255,255,255,.06) 0);
  box-shadow:0 0 34px rgba(57,255,106,.16);
}
.trophy-hero .tring .inner{
  width:110px;height:110px;border-radius:50%;background:var(--bg2);
  display:grid;place-content:center;text-align:center;border:1px solid var(--line);
}
.trophy-hero .tring .n{display:block;font-size:38px;font-weight:900;letter-spacing:-.04em;line-height:1}
.trophy-hero .tring .d{display:block;font-size:11.5px;color:var(--muted);margin-top:3px}
.trophy-hero .who{flex:1 1 250px;min-width:230px}
.trophy-hero h1{margin:2px 0 4px;font-size:32px}
.trophy-hero .rank{
  display:inline-flex;align-items:center;gap:7px;padding:5px 13px;border-radius:999px;
  background:rgba(255,201,59,.13);border:1px solid rgba(255,201,59,.35);
  color:var(--gold);font-weight:900;font-size:12px;letter-spacing:.08em;text-transform:uppercase;
}
.trophy-hero .rank .g{display:block;width:15px;height:15px;flex:none}
.trophy-hero p{margin:0}
.trophy-hero .heroactions{display:flex;gap:8px;flex-wrap:wrap}

.tierline{display:flex;gap:8px;flex-wrap:wrap;margin-top:13px}
.tpill{
  display:inline-flex;align-items:center;gap:7px;padding:5px 12px;border-radius:999px;
  background:rgba(0,0,0,.28);border:1px solid var(--line);
  font-weight:900;font-size:13px;color:var(--ink);
}
.tpill i{
  width:12px;height:12px;border-radius:50%;flex:none;
  background:radial-gradient(circle at 34% 28%, var(--tg), var(--t1) 55%, var(--t2));
  box-shadow:
    inset 0 0 0 .5px color-mix(in srgb, var(--tg) 60%, transparent),
    0 0 8px color-mix(in srgb, var(--t1) 45%, transparent);
}
.tpill em{font-style:normal;font-weight:700;font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.06em}

/* ---- the podium coin -----------------------------------------------------
   Only the ranking podium uses this now: a struck coin with a conic sweep for
   the sheen real metal has, a milled edge and the place number engraved into
   the recessed field. Badges use .crest below. */
.disc{
  --sz:40px;
  width:var(--sz);height:var(--sz);border-radius:50%;flex:none;
  position:relative;display:grid;place-items:center;isolation:isolate;
  background:conic-gradient(from 216deg,
    var(--t2)   0deg, var(--t1)  36deg, var(--tg)  64deg, var(--t1) 102deg,
    var(--t2) 148deg, var(--t1) 194deg, var(--tg) 230deg, var(--t1) 272deg,
    var(--t2) 316deg, var(--t1) 350deg, var(--t2) 360deg);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--tg) 55%, transparent),
    0 6px 16px rgba(0,0,0,.45);
}
/* milled edge - only the outer fifth of the coin */
.disc::before{
  content:"";position:absolute;inset:0;border-radius:50%;z-index:1;
  pointer-events:none;opacity:.62;
  background:repeating-conic-gradient(from 0deg,
    rgba(0,0,0,.40) 0 2.5deg, rgba(255,255,255,.30) 2.5deg 5deg);
  -webkit-mask:radial-gradient(circle at 50% 50%, transparent 0 74%, #000 75%);
          mask:radial-gradient(circle at 50% 50%, transparent 0 74%, #000 75%);
}
/* the sunken field the glyph sits in */
.disc::after{
  content:"";position:absolute;inset:13%;border-radius:50%;z-index:1;
  pointer-events:none;
  background:radial-gradient(circle at 36% 28%,
    var(--tg), var(--t1) 52%, color-mix(in srgb, var(--t2) 78%, var(--t1)) 100%);
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,.40),
    inset 0 -2px 3px color-mix(in srgb, var(--tg) 55%, transparent),
    0 1px 0 color-mix(in srgb, var(--tg) 45%, transparent);
}
.disc .g{
  position:relative;z-index:2;display:block;width:54%;height:54%;
  color:color-mix(in srgb, var(--t2) 72%, #0A0C10);
  filter:drop-shadow(0 1px 0 color-mix(in srgb, var(--tg) 85%, transparent));
}

/* ---- the crest -----------------------------------------------------------
   A shield framed in the tier's metal and faced in the colour of whatever the
   badge measures - every badge on one ladder shares a hue, so a group reads as
   a few coloured families instead of 147 loose tiles. The face carries either
   a glyph or, where the number is the whole point, the number itself. */
:root{
  --shield:polygon(5% 0,95% 0,100% 8%,100% 48%,94% 66%,82% 82%,
                   62% 95%,50% 100%,38% 95%,18% 82%,6% 66%,0 48%,0 8%);
}
.crest{
  --sz:34px;
  width:var(--sz);height:calc(var(--sz) * 1.16);flex:none;
  position:relative;display:grid;place-items:center;isolation:isolate;
  clip-path:var(--shield);
  background:linear-gradient(150deg, var(--tg), var(--t1) 30%, var(--t1) 55%, var(--t2));
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.5));
}
/* the coloured face, inside the metal frame */
.crest::before{
  content:"";position:absolute;inset:13% 12% 17%;clip-path:var(--shield);z-index:1;
  background:linear-gradient(180deg,
    hsl(var(--h) 88% 57%), hsl(var(--h) 82% 43%) 55%, hsl(var(--h) 80% 28%));
}
/* gloss: a hard-edged highlight across the top, the way enamel catches light */
.crest::after{
  content:"";position:absolute;inset:13% 12% 17%;clip-path:var(--shield);z-index:2;
  background:linear-gradient(180deg,
    rgba(255,255,255,.46), rgba(255,255,255,.13) 43%,
    rgba(255,255,255,0) 45%, rgba(0,0,0,.22));
}
.crest .g{
  position:relative;z-index:3;display:block;width:52%;height:52%;color:#fff;
  filter:drop-shadow(0 1px 1.5px rgba(0,0,0,.55));
}
.crest .nn{
  position:relative;z-index:3;color:#fff;font-weight:900;line-height:1;
  font-size:calc(var(--sz) * .40);letter-spacing:-.04em;
  text-shadow:0 1px 2px rgba(0,0,0,.5);
}
.crest .nn[data-len="3"]{font-size:calc(var(--sz) * .32);letter-spacing:-.06em}

/* ---- showcase ----------------------------------------------------------- */
.showcase{display:grid;grid-template-columns:repeat(auto-fill,minmax(78px,1fr));
  gap:13px 6px;margin-top:14px;align-content:start;align-items:start}
.medal{text-align:center;position:relative}
.medal .crest{--sz:40px;margin:0 auto 7px}
.medal .ds{font-size:10px;color:var(--dim);line-height:1.3;margin-top:3px}
.medal .nm{font-size:10.5px;font-weight:800;color:var(--muted);line-height:1.25;
  min-height:2.5em}
/* ---- closest to earning ------------------------------------------------- */
.nextrow{
  display:flex;align-items:center;gap:11px;padding:9px 0;
  border-bottom:1px solid rgba(255,255,255,.05);
}
.nextrow:last-child{border-bottom:0}
.nextrow .crest{--sz:24px}
.nextrow{flex-wrap:wrap}
.nextrow .nx{flex:1 1 150px;min-width:0}
.nextrow .nx .nm{display:block;flex:none;font-weight:800;font-size:13.5px;
  color:var(--ink);white-space:normal}
.nextrow .nx .ds{display:block;font-size:11px;color:var(--dim);line-height:1.3;
  margin-top:2px}
.nextrow .nm{font-weight:800;font-size:13.5px;flex:0 1 150px;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nextrow .track{flex:1 1 60px;height:7px;border-radius:4px;background:rgba(255,255,255,.07);overflow:hidden;min-width:50px}
.nextrow .track i{display:block;height:100%;border-radius:4px;
  background:linear-gradient(90deg,var(--green),var(--blue))}
.nextrow .pc{font-size:13px;font-weight:900;color:var(--green);min-width:44px;text-align:right}
.nextrow .pc small{font-size:9px;opacity:.75}

/* ---- filter bar --------------------------------------------------------- */
.cabinet-bar{display:flex;align-items:center;gap:12px;margin:26px 0 14px;flex-wrap:wrap}
.cabinet-bar .chip{font-size:13px}
.cabinet-bar .chip.on{
  color:#06131C;background:var(--green);border-color:var(--green);
}
#cabinet[data-filter="got"] .ach.locked{display:none}
#cabinet[data-filter="locked"] .ach.got{display:none}

/* ---- group heading ------------------------------------------------------ */
.achgroup{margin-top:26px}
.achgroup .ghead{display:flex;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.achgroup .ghead h2{margin:0;font-size:21px}
.achgroup .gcount{
  font-size:11.5px;font-weight:900;color:var(--muted);padding:3px 10px;border-radius:999px;
  background:var(--surface2);border:1px solid var(--line);
}
.achgroup .gtrack{
  flex:1 1 90px;min-width:80px;height:5px;border-radius:3px;
  background:rgba(255,255,255,.07);overflow:hidden;
}
.achgroup .gtrack i{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,var(--green),var(--blue))}

/* ---- the tiles ---------------------------------------------------------- */
.ach-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:8px}
.ach{
  position:relative;padding:12px 9px 10px;border-radius:14px;text-align:center;
  background:var(--surface);border:1px solid var(--line);
  transition:transform .16s, box-shadow .16s, border-color .16s;
}
.ach .crest{margin:0 auto 7px}
/* explicit, so no ancestor can tint it - a nav pill once did */
.ach .nm{font-weight:900;font-size:12px;letter-spacing:-.01em;color:var(--ink);line-height:1.25}
.ach .ds{font-size:10px;color:var(--dim);margin-top:3px;line-height:1.3;min-height:26px}
.ach .state{font-size:9.5px;margin-top:6px;font-weight:800;color:var(--dim);
  text-transform:uppercase;letter-spacing:.07em}
.ach .track{height:5px;border-radius:3px;background:rgba(255,255,255,.08);overflow:hidden;margin-top:10px}
.ach .track i{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,var(--green),var(--blue))}

/* earned: the tile picks up the badge's own colour, and the tier's metal
   still names itself underneath */
.ach.got{
  border-color:hsl(var(--h) 38% 28%);
  background:
    radial-gradient(130% 95% at 50% 0%, hsl(var(--h) 65% 45% / .11), transparent 72%),
    var(--surface);
  box-shadow:0 5px 16px rgba(0,0,0,.32);
}
.ach.got .crest{filter:drop-shadow(0 2px 6px hsl(var(--h) 80% 45% / .45))}
.ach.got .state.done{color:var(--t1)}
.ach.got:hover{transform:translateY(-3px);box-shadow:0 12px 28px rgba(0,0,0,.42)}

/* locked: the same shield, unpainted and unfinished */
.ach.locked .crest{
  --t1:#39434F; --t2:#141A22; --tg:#5C6877;
  filter:drop-shadow(0 2px 3px rgba(0,0,0,.4));
}
.ach.locked .crest::before{background:linear-gradient(180deg,#2E3743,#1C242E 55%,#141A22)}
.ach.locked .crest::after{
  background:linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.04) 43%,
             rgba(255,255,255,0) 45%, rgba(0,0,0,.2));
}
.ach.locked .crest .g,.ach.locked .crest .nn{
  color:#606D7C;filter:none;text-shadow:none;
}
.ach.locked .nm{color:var(--muted)}

@media (max-width:640px){
  .trophy-hero{padding:18px;gap:16px}
  .trophy-hero .tring{width:104px;height:104px}
  .trophy-hero .tring .inner{width:86px;height:86px}
  .trophy-hero .tring .n{font-size:30px}
  .trophy-hero h1{font-size:25px}
  .ach-grid{grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:7px}
  .ach{padding:10px 7px 9px}
  /* Folded away by default - 147 tiles with two lines each is a page nobody
     reaches the bottom of - and opened by tapping the tile. Before this the
     description was hidden here and otherwise only in a title attribute,
     which a touch screen never shows: on a phone there was no way at all to
     find out what a badge was for. */
  .ach{cursor:pointer}
  .ach .ds{display:none}
  .ach.open .ds{display:block;min-height:0}
  .ach.open{outline:1px solid rgba(255,255,255,.18)}
  .ach .crest{--sz:30px}
  .medal .crest{--sz:36px}
}

/* ==========================================================================
   RANKING
   ========================================================================== */
.podium{
  display:flex;gap:12px;align-items:flex-end;justify-content:center;
  flex-wrap:wrap;margin:4px 0 22px;
}
.pod .av{--sz:70px}
.pod{
  flex:0 1 168px;min-width:132px;text-align:center;position:relative;
  padding:10px 10px 0;border-radius:var(--r) var(--r) 0 0;
  background:linear-gradient(180deg, color-mix(in srgb, var(--who) 9%, transparent), transparent 62%);
}
.pod .disc.place{--sz:38px;margin:0 auto 8px}
/* .av is a grid box, so text-align on the podium never centred it */
.pod .av{margin:0 auto}
.pod.p1 .disc.place{--sz:46px}
/* the place number is engraved exactly the way the badge glyphs are */
.disc b{
  position:relative;z-index:2;font-weight:900;font-size:calc(var(--sz) * .42);
  line-height:1;letter-spacing:-.02em;
  color:color-mix(in srgb, var(--t2) 72%, #0A0C10);
  text-shadow:0 1px 0 color-mix(in srgb, var(--tg) 85%, transparent);
}
.empty-state .big-g{
  width:52px;height:52px;margin:0 auto 12px;display:block;
  color:var(--muted);opacity:.45;
}
.pod .nm{font-weight:900;font-size:14px;margin-top:7px;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pod .vv{font-size:24px;font-weight:900;color:var(--who);letter-spacing:-.03em;margin:2px 0 8px}
.pod .vv small{font-size:13px;opacity:.75;margin-left:1px}
.pod .plinth{
  border-radius:12px 12px 0 0;background:var(--surface);border:1px solid var(--line);
  border-bottom:0;display:grid;place-items:center;font-weight:900;font-size:22px;color:var(--dim);
}
.pod.p1 .plinth{height:56px;background:linear-gradient(180deg,rgba(255,201,59,.16),var(--surface))}
.pod.p2 .plinth{height:40px}
.pod.p3 .plinth{height:28px}
.pod.p1{order:2}
.pod.p2{order:1}
.pod.p3{order:3}

.rank-table{min-width:560px}
.rank-table th.r,.rank-table td.r{text-align:right}
.rank-table td{vertical-align:middle}
.rank-table .pl{width:56px;text-align:center}
.rank-table .pos{
  display:inline-grid;place-items:center;width:30px;height:30px;border-radius:50%;
  background:var(--surface2);border:1px solid var(--line);
  font-weight:900;font-size:13px;color:var(--muted);
}
.rank-table .pos.top{background:rgba(255,201,59,.15);border-color:rgba(255,201,59,.4);color:var(--gold)}
.rank-table .pos.none{opacity:.4}
.rank-table .who{display:flex;align-items:center;gap:10px;min-width:0}
.rank-table .who .av{--sz:34px}
.rank-table .who .nm{font-weight:800;font-size:14.5px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.rank-table .who .note{font-size:11px;color:var(--dim);margin-top:1px}
.rank-table .val{font-size:18px;font-weight:900;letter-spacing:-.02em;white-space:nowrap}
.rank-table .val small{font-size:11px;color:var(--muted);margin-left:1px}
.rank-table .bar-col{width:150px}
.rank-table .bar-col .bar{min-width:60px}
.rank-table tr.me{background:rgba(57,255,106,.06)}
.rank-table tr.me td:first-child{box-shadow:inset 3px 0 0 var(--green)}
.rank-table tr.prov{opacity:.62}
.rank-table td.dim{color:var(--dim);font-size:13px}

.ratingparts{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));
  gap:10px;margin-top:12px;
}
.rp{padding:11px 13px;border-radius:14px;background:rgba(0,0,0,.22);border:1px solid var(--line)}
.rp .k{font-size:12px;font-weight:800;color:var(--muted)}
.rp .w{font-size:21px;font-weight:900;color:var(--green);letter-spacing:-.02em;margin:3px 0 1px}
.rp .w small{font-size:11px;color:var(--muted);margin-left:2px;font-weight:700}
.rp .c{font-size:10.5px;color:var(--dim)}

@media (max-width:640px){
  .hide-sm{display:none}
  .rank-table{min-width:0}
  .rank-table .bar-col{width:72px}
  .pod{flex:1 1 100px;min-width:100px}
  .pod .vv{font-size:21px}
  .pod .nm{font-size:13px}
}


/* ==========================================================================
   PLAYING FROM TWO HOUSES
   ========================================================================== */
.turnbar{
  display:block;width:100%;margin:0 0 6px;padding:7px 14px;border-radius:12px;
  text-align:center;font:inherit;
  font-weight:900;font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;
}
.turnbar:disabled{cursor:default}
/* Kept in the grid rather than hidden: a hidden item is not an item, and the
   board would slide up into the banner's row. */
.turnbar.off{
  height:0;padding:0;margin:0;border:0;overflow:hidden;visibility:hidden;
}
.turnbar.takeable{cursor:pointer;text-decoration:underline dotted;text-underline-offset:3px}
.turnbar.mine{
  color:var(--green);background:color-mix(in srgb, var(--green) 13%, transparent);
  border:1px solid color-mix(in srgb, var(--green) 40%, transparent);
}
.turnbar.waiting{
  color:var(--gold);background:color-mix(in srgb, var(--gold) 11%, transparent);
  border:1px solid color-mix(in srgb, var(--gold) 32%, transparent);
  letter-spacing:.06em;
}
/* The pad stays visible while the other end throws - hiding it would make the
   screen look broken - but it must not look tappable. */
body.notmyturn .pad{opacity:.42;filter:saturate(.35)}
body.notmyturn .pad button{cursor:not-allowed}
body.notmyturn .checkout{opacity:.55}

/* a game somebody else is in, waiting on the home screen */
.livegames{display:grid;gap:8px;margin:0 0 22px}
.livegame{
  display:flex;align-items:center;gap:12px;padding:12px 15px;border-radius:16px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(57,255,106,.10), transparent 62%),
    var(--surface);
  border:1px solid color-mix(in srgb, var(--green) 32%, transparent);
  color:var(--ink);text-decoration:none;
}
.livegame .dot{
  width:9px;height:9px;border-radius:50%;background:var(--green);flex:none;
  box-shadow:0 0 0 0 color-mix(in srgb, var(--green) 70%, transparent);
  animation:livepulse 2s infinite;
}
@keyframes livepulse{
  70%{box-shadow:0 0 0 9px rgba(57,255,106,0)}
  100%{box-shadow:0 0 0 0 rgba(57,255,106,0)}
}
@media (prefers-reduced-motion:reduce){ .livegame .dot{animation:none} }
.livegame .nm{font-weight:900;font-size:15px}
.livegame .who{font-size:12px;color:var(--muted);margin-top:1px}
.livegame .go{margin-left:auto;font-weight:900;color:var(--green);font-size:13px}
.livegame .yours{
  font-size:10px;font-weight:900;letter-spacing:.08em;text-transform:uppercase;
  color:#06131C;background:var(--green);padding:2px 7px;border-radius:999px;
  margin-left:8px;
}


/* ---- one board or a screen each ---------------------------------------- */
.where{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}
.wcard{
  display:grid;gap:5px;justify-items:start;text-align:left;cursor:pointer;
  padding:15px 16px;border-radius:16px;font:inherit;
  background:var(--surface);border:1px solid var(--line);color:var(--ink);
}
.wcard svg{width:26px;height:26px;color:var(--muted)}
.wcard .t{font-weight:900;font-size:15px}
.wcard .d{font-size:12px;color:var(--dim);line-height:1.4}
.wcard.on{
  border-color:var(--green);
  background:color-mix(in srgb, var(--green) 10%, var(--surface));
}
.wcard.on svg,.wcard.on .t{color:var(--green)}

/* ---- the invitation ----------------------------------------------------- */
.invite-veil{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:20px;
  background:rgba(6,10,14,.82);backdrop-filter:blur(7px);
}
.invite-card{
  width:min(420px,100%);text-align:center;padding:28px 24px;border-radius:var(--r-lg);
  background:
    radial-gradient(130% 130% at 50% 0%, rgba(57,255,106,.12), transparent 62%),
    var(--surface);
  border:1px solid var(--line);box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.invite-card .ic{
  width:56px;height:56px;margin:0 auto 14px;border-radius:50%;display:grid;
  place-items:center;color:var(--green);
  background:color-mix(in srgb, var(--green) 14%, transparent);
  border:1px solid color-mix(in srgb, var(--green) 38%, transparent);
}
.invite-card .ic svg{width:26px;height:26px}
.invite-card h2{margin:0 0 6px;font-size:23px}
.invite-card p{margin:0}
.invite-card .row{gap:10px;justify-content:center}
.invite-card .row .btn{flex:1 1 0;min-width:0}

/* ---- an invitation waiting on the home screen --------------------------- */
.livegame.invited{
  border-color:color-mix(in srgb, var(--gold) 45%, transparent);
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(255,201,59,.12), transparent 62%),
    var(--surface);
}
.livegame.invited .dot{background:var(--gold);animation:none}
.livegame .asks{
  font-size:10px;font-weight:900;letter-spacing:.08em;text-transform:uppercase;
  color:#1a1204;background:var(--gold);padding:2px 7px;border-radius:999px;
  margin-left:8px;
}


/* ---- the caller's settings ---------------------------------------------- */
.callrow{
  display:flex;align-items:center;gap:12px;padding:11px 2px;
  border-bottom:1px solid rgba(255,255,255,.06);font-weight:800;font-size:14.5px;
}
.callrow span{flex:1}
.callrow input[type="checkbox"]{width:22px;height:22px;accent-color:var(--green)}
#callVoice{width:100%}
#callRate{width:100%;accent-color:var(--green)}
.callhint{font-size:11.5px;line-height:1.45;margin:7px 0 0}

/* ==========================================================================
   Share
   ========================================================================== */
.share-btn{padding:10px 16px;font-size:14px;gap:7px}
.sharemenu{
  display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;padding:8px;
  background:var(--surface2);border:1px solid var(--line2);
  border-radius:var(--r-sm);
}
.sharemenu a,.sharemenu button{
  padding:9px 13px;border-radius:8px;border:1px solid var(--line);
  background:rgba(0,0,0,.25);color:var(--ink);font:inherit;font-size:13px;
  font-weight:800;text-decoration:none;cursor:pointer;
}
.sharemenu a:hover,.sharemenu button:hover{border-color:var(--line2)}


/* Admin "People": on a phone the email moves under the username, because the
   email column itself is hidden there. An address is one long unbreakable
   token, so without this it widens the cell and pushes the State pill off the
   right-hand edge. */
@media (max-width:640px){
  .rank-table .admin-mail{
    display:block;
    overflow-wrap:anywhere;
    font-size:10.5px;
    line-height:1.35;
  }
}


/* ==========================================================================
   Badge popup
   --------------------------------------------------------------------------
   Lands mid-game, over the board. It must read instantly and get out of the
   way just as fast - the darts are still in someone's hand.
   ========================================================================== */
.badge-pop{
  /* Above the big-score banner (120) and the toasts (130): this is a modal,
     and a celebration half-covered by another celebration reads as a bug. */
  position:fixed;inset:0;z-index:140;
  display:grid;place-items:center;padding:20px;
  background:rgba(4,7,11,.72);
  backdrop-filter:blur(3px);
  animation:badgepop-in .16s ease-out;
}
@keyframes badgepop-in{from{opacity:0}to{opacity:1}}

.badge-pop-card{
  width:min(420px,100%);
  background:linear-gradient(180deg,var(--surface2),var(--surface));
  border:1px solid var(--line2);border-radius:22px;
  padding:26px 22px 20px;text-align:center;
  box-shadow:0 24px 60px rgba(0,0,0,.6);
  animation:badgepop-rise .22s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes badgepop-rise{from{transform:translateY(14px) scale(.96);opacity:0}
                         to{transform:none;opacity:1}}

.badge-pop-eyebrow{
  font-size:11px;font-weight:900;letter-spacing:.14em;
  color:var(--gold);margin-bottom:14px;
}
/* The crest is the same component the badges page collects, drawn large. */
.badge-pop-crest .crest{--sz:96px;margin:0 auto}
.badge-pop-name{font-size:clamp(23px,5.2vw,30px);margin:16px 0 6px;line-height:1.15}
.badge-pop-desc{color:var(--muted);font-size:14px;margin:0 0 10px;line-height:1.45}
.badge-pop-group{
  display:inline-block;font-size:11px;font-weight:800;letter-spacing:.06em;
  color:var(--dim);border:1px solid var(--line2);border-radius:999px;
  padding:3px 10px;margin-bottom:18px;
}
.badge-pop-actions{display:flex;gap:10px}
.badge-pop-actions .btn{flex:1 1 0;justify-content:center}
.badge-pop-more{margin-top:12px;font-size:12px;color:var(--dim);font-weight:700}

@media (prefers-reduced-motion:reduce){
  .badge-pop,.badge-pop-card{animation:none}
}
