/* ==========================================================================
   GRIDROP · OVERTAKE — the owner's approved GAME TABLE, in the real game.

   Source of truth: the owner's "GRIDROP Game Table" design. Every colour,
   gradient, radius, clip and keyframe below is lifted from it verbatim — the
   conic rim, the felt, the neon ring that follows the clock, the socket grid,
   the metal cards, the banner leaderboard, the stopwatch plate.

   TWO THINGS THE DESIGN DID NOT HAVE, and the owner asked for by name:
     • the card's VALUE (the design printed the letter in both corners)
     • its COLOUR — the value now carries a tier tint, so a 10 is visible
       across the table without reading the digit.

   Sizes here are all variables. felt.js measures the arena, scales the whole
   composition by one factor k, and writes them — so the design keeps its own
   proportions on a 1600px monitor and on a phone lying down.
   ========================================================================== */

body.ot-felt{
  --fneon:#45eded;               /* the design's neon — table ring, rails, accents */
  --ffelt:#143440;               /* the felt */
  --fgold:#f0c04f;
  --fink:#eafcff;                /* the design's text white */
  --fmut:rgba(214,240,246,.65);
  --fmetal:linear-gradient(165deg,#e8edf2 0%,#b9c2cb 28%,#f2f6f9 46%,#97a1aa 68%,#d6dde3 100%);
  --frim:conic-gradient(from 180deg,#4a545d,#77828b 12%,#39434c 26%,#8b959e 40%,#444e57 55%,#7d8891 70%,#39434c 84%,#4a545d);
  --fclock:rgb(96,224,245);      /* live, rewritten every tick by felt.js */
  --fblink:1;
}

/* ---- the page gets out of the way ------------------------------------- */
body.ot-felt{background:radial-gradient(120% 120% at 50% 30%,#1c252d 0%,#121920 46%,#0a0f13 100%)!important}
/* EVERY SCREEN IS THE WHOLE SCREEN — the owner, twice: "for every screen I
   told you I want a full screen; the edge will eat the text." The page used
   to dress itself in an 8px body margin, a 1080px frame and a bordered,
   rounded, padded stage — and the stage clips, so all of that was a band of
   backdrop with the game visibly cut off inside it. Menus and results keep a
   little inner breathing room for their text; the table keeps none, because
   its own artwork is the edge. (These rules are page-wide but this file only
   loads on the Overtake pages — other games are untouched.) */
body{padding:0!important}
.frame{max-width:none!important;margin:0!important;width:100%}
.stage{border:0!important;border-radius:0!important;box-shadow:none!important;
  padding:calc(8px + env(safe-area-inset-top)) calc(10px + env(safe-area-inset-right))
          calc(8px + env(safe-area-inset-bottom)) calc(10px + env(safe-area-inset-left))!important}
body.ot-felt .frame{padding:0;position:relative}   /* the table layer mounts HERE, outside #scr */
body.ot-felt .stage{padding:env(safe-area-inset-top) env(safe-area-inset-right)
          env(safe-area-inset-bottom) env(safe-area-inset-left)!important}
/* One cell. The NAME is load-bearing: the game places .arena-cen by
   `grid-area:c`, so a template without that area drops it into an implicit
   zero-width track — the table then measures 0 wide and never paints. */
body.ot-felt .arena{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);
  grid-template-areas:"c";gap:0;padding:0;padding-top:0;min-height:0}
body.ot-felt .side,
body.ot-felt .arena-title,
body.ot-felt .poollbl,
body.ot-felt .handlbl,
body.ot-felt .subhint{display:none!important}
/* EXCEPT the word-feedback line: it carries the SUGGEST-A-WORD flow the owner asked
   for (2026-08-01) — a rejected word shows «ليست كلمة · أتقترح هذه الكلمة؟» and the
   button files it straight to the admin approval queue; approved words then pass the
   dictionary AND the common-words gate. The felt was hiding the whole line. */
/* WHERE IT STANDS: THE TOP OF THE TABLE, ON THE RIGHT — the owner, 2026-08-02:
   «انا ودي نخليها في اعلى الطاولة احسن في جهة اليمين صح».
   It used to live in the LEFT margin (left:10px, top:calc(50% + 96px),
   width:170px). That column has four tenants — clock, word plate, this line and
   the wildcard card — and at 390px tall it seats three, so this line landed ON
   the card (x20-84, y298-384) and the owner could read neither the «ليست كلمة»
   verdict nor reach the suggest button. A short-screen-only toast fixed the
   collision but left TWO competing positions for one element; the column is
   crowded at every size, so there is now ONE position for every size.

   THE RIGHT EDGE IS THE RAIL'S EDGE, NOT A GUESSED CONSTANT. The players rail
   (.ofelt-lb) runs flush from the screen's top edge to its bottom one, and
   felt.js publishes its measured width as --lbW — but it publishes it ON
   .ofelt-lb, and this line is not a descendant of the rail (the rail lives in
   the .ofelt layer on .frame, #fb lives in the game's own column inside .stage),
   so that variable does not inherit down to here. --fbRail is therefore the same
   ARITHMETIC read off the viewport instead of measured — felt.js:
     lbW = (W<=1024 ? clamp(W*.175,108,190) : clamp(W*.265,150,424)) * seatFactor
   with the NINE-SEATS-AND-UP factor (0.94) mirrored on purpose: that is the
   WIDEST the rail ever gets, so the line clears it at every seat count instead of
   only at a small table. var(--lbW,…) is kept in front of the fallback so the
   measured width takes over for free the day felt.js publishes it where this
   element can see it.

   PHYSICAL `right`, NOT inset-inline-end. felt.js pins the rail with
   `lb.style.right='0px'` and never flips it, so «جهة اليمين» is the same side of
   the glass in Arabic as in English. A logical inset resolves against this
   element's own direction — and overtake.html gives body.ar .subhint
   direction:rtl — so it would send the line to the FAR side, straight through the
   word plate, in exactly the language the owner asked in.

   THE TOP IS THE ROUND PLATE'S FLOOR. .ofelt-round stands at top:--fpad (10px)
   and felt.js sizes it roundH = clamp(chipH*1.45,34,66) with
   chipH = clamp(H*.075,28,46) — a floor of 10px + clamp(40.6px,10.875vh,66px),
   reproduced here from the viewport rather than capped at one pixel value. That
   matters most on a SHORT screen, where felt.js's `oneRow` (H<620) tucks the
   plate against the rail — this exact corner. The same offset also clears
   .ofelt-lbtog (top:8px, 34px tall), the rail's hide button, which sits at
   right:lbW+8 and would otherwise be under the message.

   IT NEVER TAKES A TAP. At the top of the table it stands over the first row of
   places, so the box is transparent to the pointer and only .suggbtn takes
   clicks back — a card under this line is still a card you can pick up. */
/* ⚠️ LAST-RESORT ONLY, AND NO BREAKPOINT. felt.js now publishes its MEASURED
   --lbW on :root (felt.js:1074), so `var(--lbW,var(--fbRail))` below resolves to
   the real rail from the first solve onward and this value is what stands for the
   one frame before it. The old pair duplicated felt.js:768-778's arithmetic by
   hand — with the 9-seat factor 0.94 baked in where a normal table uses 0.85, so
   it was 0.905 of the truth at every size (measured 144.8 vs 131.0 at 880x400) —
   and it stepped 152px → 231px between 1024 and 1025 viewport pixels. This is the
   small-table formula (0.175 * 0.85 = 14.875vw, floor 108*0.85, cap 190*0.85)
   written once, continuously, with no query. */
body.ot-felt{--fbRail:clamp(92px,14.875vw,161px)}
body.ot-felt #fb.subhint{display:block!important;position:fixed;z-index:120;
  left:auto;width:auto;max-width:min(46vw,430px);
  right:calc(env(safe-area-inset-right,0px) + var(--lbW,var(--fbRail)) + 10px);
  /* ⚠️ BELOW THE WHOLE CORNER COLUMN, NOT BESIDE IT. `right` above resolves from
     the rail width, which puts this pill in EXACTLY the column the corner buttons
     stand in (.otcn-btn, corner.js:244) — and the old top resolved to 61.5px,
     inside the gear's band. Measured 880x400: overlap 34.0 x 19.5px = 57% of the
     button, 66% at 740x360, plus 45.3 x 4.4px of the rightmost pool card.
     160 = 8 (lbtog top) + 3 x 44 (the buttons) + 2 x 6 (their gaps) + 8 (clear).
     ⚠️ IF THE BUTTONS CHANGE SIZE, THIS CHANGES WITH THEM — it is derived from
     felt.css:928 and corner.js:244/263, which is why those ship in this commit. */
  top:calc(env(safe-area-inset-top,0px) + 160px);
  pointer-events:none;
  font:700 11.5px Cairo,sans-serif;color:#f0c04f;text-align:center;line-height:1.55;
  /* the pill the toast wore, kept: bare gold text over seven letter cards is
     unreadable. No backdrop blur — at .94 the tint already hides the felt, and
     this file's own rule is that phones do not pay for glass they cannot see. */
  background:rgba(4,12,16,.94);border:1px solid rgba(240,192,79,.42);border-radius:999px;
  padding:5px 15px;box-shadow:0 10px 30px -14px rgba(0,0,0,.9)}
body.ot-felt #fb.subhint.ok{color:#7fe0a0;border-color:rgba(127,224,160,.42)}
body.ot-felt #fb.subhint .suggbtn{display:inline-block;margin-inline-start:7px;
  padding:4px 11px;border-radius:999px;pointer-events:auto;
  background:rgba(10,182,212,.16);border:1px solid rgba(76,215,246,.55);color:#7FE3F5;cursor:pointer;font-weight:800}
/* THE RAIL CAN BE SENT AWAY. felt.js's hide button parks the rail off the screen
   (body.ot-lbhide) and moves itself to right:8px — the reservation above would
   then leave this line hanging a rail's width from an empty edge, so it follows
   the button in: 34px of button + 8px + 10px. */
body.ot-lbhide.ot-felt #fb.subhint{right:calc(env(safe-area-inset-right,0px) + 52px)}
body.ot-felt .roster{display:none!important}
body.ot-felt .arena-cen{position:relative;min-height:0;display:block;overflow:visible}
body.ot-felt .col{gap:0;height:100%;min-height:0}
/* the game header is replaced outright by the design's own chrome (exit chip,
   round plate, stopwatch). Its BUTTONS are not thrown away — felt.js moves the
   live elements into the chrome, so every handler survives.
   ONLINE carries a second header of its own (`.hdr`: wordmark, round, Leave).
   Both are collapsed here — otherwise the page prints the round twice and
   offers two ways out, which the owner has already called a mistake once. */
body.ot-felt .chdr,
body.ot-felt .hdr{position:absolute!important;left:0;right:0;top:0;height:0!important;
  min-height:0!important;padding:0!important;margin:0!important;border:0!important;
  background:none!important;box-shadow:none!important;overflow:visible;pointer-events:none;z-index:30}
body.ot-felt .chdr > *,
body.ot-felt .hdr > *{display:none!important}
body.ot-felt .hlogo,
body.ot-felt .ch-mid{display:none!important}
body.ot-felt .gx-btn.gx-float{display:none!important}

/* ======================================================================== */
/*  THE LAYER                                                               */
/* ======================================================================== */
.ofelt{position:absolute;inset:0;z-index:1;pointer-events:none}
.ofelt > *{pointer-events:auto}

/* the design's ambient wash — a neon pool low-left, a cold one up top */
.ofelt-amb{display:none}   /* the ambient neon pools went with the ring */

/* ======================================================================== */
/*  THE TABLE — an ellipse of milled steel, tilted away from you            */
/* ======================================================================== */
.ofelt-table{position:absolute;z-index:2;pointer-events:none}
.ofelt-plate{position:absolute;inset:0;border-radius:50%;transform-style:preserve-3d;
  transform-origin:center 42%;background:var(--frim);
  box-shadow:
    0 var(--fdep,56px) calc(var(--fdep,56px)*1.6) rgba(0,0,0,.72),
    inset 0 3px 0 rgba(230,240,244,.32),
    inset 0 -6px 18px rgba(0,0,0,.55)}
.ofelt-plate > *{pointer-events:none}

/* the dark step between rim and felt */
.ofelt-lip{position:absolute;inset:var(--flip,26px);border-radius:50%;
  background:linear-gradient(180deg,#10181e,#060b0f);
  box-shadow:inset 0 4px 14px rgba(0,0,0,.8)}

/* THE RING. It is the clock: cyan while there is time, orange at ten, red at
   five, and it breathes in the last five seconds. */
/* the neon ring is RETIRED at the owner's word ("remove the neon effect
   around the table") — the countdown's colour and blink live on the clock
   digits, which already carry var(--fclock) in their glow */
.ofelt-ring{display:none}

.ofelt-felt{position:absolute;inset:var(--ffeltin,44px);border-radius:50%;overflow:hidden;
  background:
    radial-gradient(58% 46% at 50% 32%,rgba(69,237,237,.16),rgba(0,0,0,0) 74%),
    linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,0) 46%,rgba(0,0,0,.38)),
    var(--ffelt);
  box-shadow:inset 0 6px 26px rgba(0,0,0,.62),inset 0 0 70px rgba(69,237,237,.12)}
/* the design's brushed pass + its vignette */
.ofelt-felt::before{content:'';position:absolute;inset:0;opacity:.2;
  background:repeating-linear-gradient(178deg,rgba(0,0,0,.5) 0 5px,rgba(210,255,255,.05) 5px 13px,rgba(0,0,0,.32) 13px 20px)}
.ofelt-felt::after{content:'';position:absolute;inset:0;
  background:
    radial-gradient(58% 52% at 50% 42%,rgba(150,250,250,.12),rgba(0,0,0,0) 74%),
    radial-gradient(120% 60% at 50% 108%,rgba(0,0,0,.5),rgba(0,0,0,0) 62%)}

/* ---- the places ------------------------------------------------------- */
/* The design nudges its field 14px off the plate's centre, because the plate
   turns about 42% of its height rather than its middle. The nudge is applied
   to the sockets AND to the board in one variable — they must never be able
   to drift apart, or a card would sit beside its own place instead of on it. */
.ofelt-slots{position:absolute;inset:0;display:grid;justify-content:center;align-content:center;
  opacity:.45;   /* owner-tuned: the empty places sit back, the cards carry the light */
  gap:var(--rg,16px) var(--cg,16px);z-index:1;pointer-events:none;
  transform:translateY(var(--gy,0px))}
.ofelt-slots .oslot{box-sizing:border-box;border-radius:var(--srad,14px);
  background:linear-gradient(180deg,rgba(9,24,30,.9),rgba(17,36,44,.65));
  border:1px solid rgba(150,220,230,.25);
  box-shadow:inset 0 3px 8px rgba(0,0,0,.6),0 1px 0 rgba(190,240,246,.07)}
/* A place does not disappear when a card lands on it — it LIGHTS, once, and
   settles back. (Owner: the light must not stay on.) */
.ofelt-slots .oslot.lit{animation:ofeltLand .85s ease-out 1}
@keyframes ofeltLand{
  0%{border-color:var(--fneon);box-shadow:inset 0 0 22px rgba(69,237,237,.75),0 0 26px rgba(69,237,237,.5)}
  55%{border-color:rgba(69,237,237,.6);box-shadow:inset 0 0 12px rgba(69,237,237,.35),0 0 12px rgba(69,237,237,.22)}
  100%{border-color:rgba(150,220,230,.25);box-shadow:inset 0 3px 8px rgba(0,0,0,.6),0 1px 0 rgba(190,240,246,.07)}}

/* ---- the game's own board, laid onto the felt -------------------------- */
body.ot-felt .board{position:absolute!important;inset:0;background:none!important;
  border:0!important;box-shadow:none!important;padding:0!important;margin:0!important;
  overflow:visible!important;border-radius:0!important;z-index:2;
  transform:translateY(var(--gy,0px))}
body.ot-felt .board::before,
body.ot-felt .board::after{display:none!important}
/* The pool becomes the design's 7-wide grid, sitting exactly on the places.
   IT FILLS THE WHOLE PLATE, and that is load-bearing rather than tidy: the
   throw is a drag-and-drop whose target is this element's own rect, so the
   drop zone is now the whole table — drag a card anywhere onto the felt and it
   lands. (The previous table grew this box by -62% to buy the same slack. On
   an ellipse this size that reaches PAST THE CAMERA, and the projected rect
   came back inside-out and far off-screen: every throw was refused.)
   Centred content, same centre as the sockets, so card and place still meet. */
/* NO TRANSLATE OF ITS OWN — the pool rides inside .board, which already
   carries the design's --gy nudge (see above). Nudging here as well moved
   every card a second time and floated the whole deal half a socket above
   its places. The sockets and the cards must share ONE journey. */
body.ot-felt .pool{display:grid!important;position:absolute;inset:0;z-index:2;
  grid-template-columns:repeat(7,var(--sw,50px));
  gap:var(--rg,16px) var(--cg,16px);
  justify-content:center;align-content:center;
  background:none!important;border:0!important;padding:0!important;overflow:visible!important}
body.ot-felt .pool .empty{display:none}

/* THE CARDS CATCH TAPS. The table above them is artwork and deliberately does
   not — but `pointer-events` inherits, so switching the artwork off switched
   off the board, the pool and every card with it: choosing letters off the
   table to build a word stopped working entirely. A descendant set back to
   `auto` is a hit target again even inside a parent that is `none`, so only the
   cards come back and the empty felt still lets a tap fall through. */
body.ot-felt .board,
body.ot-felt .pool{pointer-events:none}
body.ot-felt .pool .pcard{pointer-events:auto}
body.ot-felt .pool .pcard.back{pointer-events:none}   /* face down: nothing to choose */

/* ======================================================================== */
/*  THE CARDS — milled steel, the letter cut into the face                  */
/* ======================================================================== */
/* :not(.back) is load-bearing. ONLINE keeps every thrown card FACE DOWN until
   the race starts, and the metal face was being painted over the back — the
   table filled with blank white cards and gave nothing away about which were
   still hidden. Backs keep their own face, restated below in this table's
   palette. */
body.ot-felt .pool .pcard:not(.back),
body.ot-felt .hand .hcard{
  position:relative;width:auto!important;height:auto!important;
  border-radius:var(--crad,12px);box-sizing:border-box;
  background:var(--fmetal)!important;
  border:var(--cbw,2px) solid var(--cedge,#f4f8fb)!important;
  color:#17222b!important;
  display:flex;align-items:center;justify-content:center;
  font-weight:800;font-family:Cairo,'Sora',sans-serif}
body.ot-felt .pool .pcard{width:var(--sw,50px)!important;height:var(--sh,59px)!important;
  box-shadow:0 8px 16px rgba(0,0,0,.55),0 0 16px rgba(120,230,240,.18),inset 0 -3px 6px rgba(60,70,80,.35)}
/* face down, in this table's own neon rather than the page's cyan */
body.ot-felt .pool .pcard.back{position:relative;box-sizing:border-box;border-radius:var(--crad,12px);
  background:linear-gradient(160deg,#173a48,#081118 58%,#12303c)!important;
  border:var(--cbw,2px) solid rgba(69,237,237,.42)!important;
  box-shadow:0 8px 16px rgba(0,0,0,.6),inset 0 0 22px -8px rgba(69,237,237,.85)!important}
body.ot-felt .pool .pcard.back::before{border-color:rgba(69,237,237,.24);
  background-image:repeating-linear-gradient(45deg,rgba(69,237,237,.12) 0,rgba(69,237,237,.12) 2px,transparent 2px,transparent 6px)}
body.ot-felt .pool .pcard.back::after{border-color:rgba(69,237,237,.8);
  box-shadow:0 0 12px -2px rgba(69,237,237,.6)}
/* An element that ANIMATES inside a preserve-3d parent is promoted to its own
   compositing layer and painted OUTSIDE the table's projection — the thrown
   card floated above the felt. The arrival is told by the place lighting up
   instead, which costs the card no layer of its own. */
body.ot-felt .pool .pcard{animation:none!important;transform:none!important}
body.ot-felt .pool .pcard:hover{transform:translateY(-3px)!important}
/* A CARD YOU HAVE CHOSEN. This is half of how the round is played — tap the
   letters off the table, in order, then send or clear — so it is stated loudly:
   the card brightens, takes a ring of the table's own neon, and carries the
   position you gave it. */
body.ot-felt .pool .pcard.sel{
  border-color:var(--fneon)!important;filter:brightness(1.07);
  box-shadow:0 0 0 var(--cbw,2px) var(--fneon),0 0 24px rgba(69,237,237,.6),
             0 10px 18px rgba(0,0,0,.55),inset 0 -3px 6px rgba(60,70,80,.35)!important}
body.ot-felt .pool .pcard .ord{position:absolute;top:0;left:50%;
  transform:translate(-50%,-50%);z-index:3;
  min-width:calc(var(--cc,10px) * 1.75);height:calc(var(--cc,10px) * 1.75);
  padding:0 2px;border-radius:999px;box-sizing:border-box;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(180deg,#8ff6f6,#0f8fa0);
  border:1px solid rgba(4,26,32,.55);
  color:#04222a;font:900 calc(var(--cc,10px) * 1.02)/1 Cairo,sans-serif;
  font-variant-numeric:tabular-nums;
  box-shadow:0 0 10px rgba(69,237,237,.85),0 2px 4px rgba(0,0,0,.5)}

/* The letter, cut deep. `.pool` is in the selector on purpose: the game sizes a
   thrown card's letter with `.pool.fit .pcard .lt`, four classes, which outranks
   anything shorter — the table's letter stayed 34px while the hand's followed
   --lt, and the same card read differently in the two places. */
body.ot-felt .pool .pcard .lt,
body.ot-felt .hand .hcard .lt{font-size:var(--lt,22px);line-height:1;font-weight:800;color:#17222b;
  text-shadow:0 1px 0 rgba(255,255,255,.55),0 -1px 0 rgba(40,50,60,.25)}
/* ---- THE FOUR CORNERS ---------------------------------------------------
   One size for a card's corner marks whatever the card is — a place on the
   table or a card in your hand — so the rules below are written once. */
body.ot-felt .pool .pcard,
body.ot-felt .hand .hcard{--vc:var(--cc,10px);--vo:var(--co,4px)}

/* THE LETTER, small, at top-right and bottom-left — the design's own corners,
   back where it drew them. */
body.ot-felt .pool .pcard .lc1,
body.ot-felt .pool .pcard .lc2,
body.ot-felt .hand .hcard .lc1,
body.ot-felt .hand .hcard .lc2{display:block!important;position:absolute;
  font-size:var(--vc,10px);line-height:1;font-weight:800;
  color:rgba(32,45,55,.75)!important;
  text-shadow:0 1px 0 rgba(255,255,255,.55)}
body.ot-felt .pool .pcard .lc1,body.ot-felt .hand .hcard .lc1{top:var(--vo);right:var(--vo);left:auto;bottom:auto}
body.ot-felt .pool .pcard .lc2,body.ot-felt .hand .hcard .lc2{bottom:var(--vo);left:var(--vo);right:auto;top:auto}

/* THE VALUE, on the other diagonal, IN A CHIP — because as plain ink it could
   not be read. The game paints a high card's corners #F4C85E, and on this
   table's polished steel that measured 1.46:1 against the light of the face:
   the owner could not see a ten at all. White on a solid tier colour is 6:1 or
   better wherever it lands on the gradient, and it cannot be undone by a rule
   that only knows about the old dark card. (Specificity here is deliberate: the
   game's `.face.dk.hi .c1` carries four classes and outranks anything lighter.) */
body.ot-felt .pool .pcard .cc.c1,
body.ot-felt .pool .pcard .cc.c2,
body.ot-felt .hand .hcard .cc.c1,
body.ot-felt .hand .hcard .cc.c2,
.otf-sw .pcard .cc.c1,
.otf-sw .pcard .cc.c2{
  position:absolute;display:flex;align-items:center;justify-content:center;box-sizing:border-box;
  min-width:calc(var(--vc,10px) * 1.3);height:calc(var(--vc,10px) * 1.3);
  padding:0 calc(var(--vc,10px) * 0.18);
  border-radius:calc(var(--vc,10px) * 0.42);
  background:var(--vink,#3a4650)!important;
  color:#fff!important;
  font:800 calc(var(--vc,10px) * 0.85)/1 Cairo,sans-serif;
  font-variant-numeric:tabular-nums;
  border:1px solid rgba(255,255,255,.4);
  box-shadow:0 1px 2px rgba(0,0,0,.4)}
body.ot-felt .pool .pcard .c1,body.ot-felt .hand .hcard .c1{top:var(--vo);left:var(--vo);right:auto;bottom:auto}
body.ot-felt .pool .pcard .c2,body.ot-felt .hand .hcard .c2{bottom:var(--vo);right:var(--vo);left:auto;top:auto}
/* THE FULL FACE, AT EVERY SIZE. A small place used to trim its card — one
   value and one letter below 46px, the bottom corners gone — and when the
   hand was made to match the table it lost its corners too. The owner asked
   where they went: his card, per his own reference, carries BOTH values and
   BOTH small letters, however small the place. The trim is retired; the
   corner marks keep their own legibility floor (--cc bottoms at 9.5px), and
   crowded beats missing. (body.ot-sm/ot-xs still mark the size on the body
   should a rule ever need it.) */

/* ---- THE COLOUR: what a letter is worth, readable across the table ----- */
/* `.otf-sw` is the CARD SWATCH scope (room setup → Play cards, overtake/menu-screen.js). The
   entry screen has no body.ot-felt, so a preview drawn there was falling back to the pale vvN
   pastels and showing the owner colours the table does not deal. Rather than copy these values
   into the menu — two lists of card colours would drift the first time one was touched — the
   swatch is simply admitted to the same rules. Colour still lives here, once. */
body.ot-felt .face.v-lo,.otf-sw .face.v-lo  {--vink:#3a4650}
body.ot-felt .face.v-mid,.otf-sw .face.v-mid {--vink:#0d6f86;--cedge:#dff4f9}
body.ot-felt .face.v-hi,.otf-sw .face.v-hi  {--vink:#8a5a12;--cedge:#fbf0d2}
body.ot-felt .face.v-top,.otf-sw .face.v-top {--vink:#8c2f12;--cedge:#ffe6c8}
/* a tier reads before the digit does: a band of its colour along the card's
   foot, and for a 10 a warm halo the eye finds from the far side of the felt */
body.ot-felt .pool .pcard.v-mid,body.ot-felt .hand .hcard.v-mid,.otf-sw .pcard.v-mid{
  background:linear-gradient(165deg,#e8f4f8 0%,#b3c7ce 28%,#f2f9fb 46%,#93a6ad 68%,#d3e2e7 100%)!important}
body.ot-felt .pool .pcard.v-hi,body.ot-felt .hand .hcard.v-hi,.otf-sw .pcard.v-hi{
  background:linear-gradient(165deg,#f4efe2 0%,#c9bda0 28%,#fbf6ea 46%,#a89a7c 68%,#e2d8c2 100%)!important}
body.ot-felt .pool .pcard.v-top,body.ot-felt .hand .hcard.v-top,.otf-sw .pcard.v-top{
  background:linear-gradient(165deg,#f8ece2 0%,#d4b49c 28%,#fdf3ea 46%,#b58f74 68%,#ecd8c6 100%)!important;
  box-shadow:0 8px 16px rgba(0,0,0,.55),0 0 20px rgba(240,160,90,.45),inset 0 -3px 6px rgba(80,60,45,.35)}
/* (The tier used to be restated as a bar along the card's foot. The value chip
   now carries that colour outright, and the bar sat under the bottom corner —
   two marks saying one thing, one on top of the other.) */

/* ======================================================================== */
/*  YOUR HAND — the design's fan, five cards of the same steel              */
/* ======================================================================== */
body.ot-felt .handwrap{position:absolute;left:0;right:0;bottom:0;height:var(--fhandH,150px);
  z-index:12;pointer-events:none;margin:0;padding:0;display:block}
/* Centred by the BOX, never by a transform: fitHand() writes an inline
   `transform:scale(k)` onto this element, which would have thrown a
   translateX(-50%) away and shoved the whole fan off to one side. */
body.ot-felt .hand{position:absolute;left:0;width:var(--fhandW,100%);bottom:var(--fhandY,10px);
  display:flex;align-items:flex-end;justify-content:center;gap:var(--hgap,6px);
  pointer-events:none;background:none;padding:0;margin:0;transform-origin:center bottom}
/* The slot's transform is the GAME's — its fan is already the design's
   -14/-7/0/+7/+14, and the drag writes translate() here on every pointermove.
   Anything !important in this slot silently disables throwing. */
body.ot-felt .hand .hslot{pointer-events:none;display:block;flex:none}
/* HOW FAR APART THEY LIE, as a fraction of the card rather than the page's flat
   -11px. That number is a fifth of the design's own 54px card and three
   quarters of the 30px one a phone was being given, so the fan closed into a
   clump and every letter but the last went behind the card in front of it. */
body.ot-felt .hand .hslot{margin-inline:var(--hfan,-4px)!important}
/* THE HELD CARD IS BIGGER THAN A PLACE ON THE TABLE — 122 against 75, which is
   the design's own relationship and the size the owner is looking at. Every
   rule above reads --sw/--sh/--lt/--cc/--co/--crad/--cbw, so the fan redefines
   exactly those for itself and inherits the face, the corners and the tiers
   without restating one of them. A card grows a little as you pick it up. */
body.ot-felt .hand{
  --sw:var(--hsw,50px); --sh:var(--hsh,59px);
  --lt:var(--hlt,22px); --cc:var(--hcc,10px); --co:var(--hco,4px);
  --crad:var(--hcrad,12px); --cbw:var(--hcbw,2px)}
body.ot-felt .hand .hcard{pointer-events:auto;
  width:var(--sw,50px)!important;height:var(--sh,59px)!important;
  box-shadow:0 12px 24px rgba(0,0,0,.58),0 0 18px rgba(120,230,240,.22),inset 0 -3px 6px rgba(60,70,80,.35);
  transition:transform .13s ease,filter .13s ease}
body.ot-felt .hand.pick .hcard{cursor:grab}
body.ot-felt .hand.pick .hcard:hover{filter:brightness(1.08) drop-shadow(0 0 12px rgba(120,230,240,.5))}

/* ======================================================================== */
/*  CHROME — exit chip, round plate, stopwatch                              */
/* ======================================================================== */
.ofelt-chip{position:absolute;z-index:20;display:flex;align-items:center;justify-content:center;
  gap:9px;border-radius:12px;box-sizing:border-box;
  background:rgba(6,18,24,.82);border:1px solid rgba(150,220,230,.25);
  box-shadow:inset 0 1px 0 rgba(210,240,248,.14),0 10px 24px rgba(0,0,0,.45)}
.ofelt-back{left:var(--fpad,20px);top:var(--fpad,14px);height:var(--fchipH,44px);padding:0 16px}
/* UNDER THE WORD PLATE the chip lives in the left column with the clock and
   the plate — and the FIELD now starts at the screen's top rim, so the chip
   must fit INSIDE the column's width or its tail would lie under the first
   socket. Tightened, and the fullscreen label yields to its icon. */
body.otbc-sideword .ofelt-back{height:32px;padding:0 8px;gap:6px}
body.otbc-sideword .ofelt-back button,
body.otbc-sideword .ofelt-back .backbtn{font-size:13px}
body.otbc-sideword .ofelt-back .ch-help{width:20px;height:20px;font-size:11px}
body.otbc-sideword .ofelt-back #fsbtn{width:20px!important;height:20px!important}
body.otbc-sideword .ofelt-back #fsbtnhint-float{display:none!important}
.ofelt-back button,.ofelt-back .backbtn,.ofelt-back .ch-help{all:unset;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  font:800 var(--fchipF,16px)/1 Cairo,sans-serif;color:#eafcff;
  text-shadow:0 0 10px rgba(69,237,237,.4);white-space:nowrap}
.ofelt-back .ch-help{width:calc(var(--fchipH,44px) * .62);height:calc(var(--fchipH,44px) * .62);
  border-radius:50%;border:1px solid rgba(150,220,230,.3);color:#7ff2f2;flex:none}
.ofelt-back button:hover{color:#7ff2f2}
/* THE FULLSCREEN CONTROL MOVES UP HERE — the owner's call: it floated in the
   bottom-right corner with its label beside it, two islands eating the rail's
   foot. Adopted into this chip it is one small square next to Back, and its
   label a word, not a plate. (External !important outranks the inline styles
   fs.js positions it with — that is what frees it from the corner.) */
.ofelt-back #fsbtn{position:static!important;left:auto!important;right:auto!important;
  bottom:auto!important;top:auto!important;margin:0!important;
  width:calc(var(--fchipH,44px) * .62)!important;height:calc(var(--fchipH,44px) * .62)!important;
  min-width:0!important;min-height:0!important;padding:0!important;
  background:none!important;border:1px solid rgba(150,220,230,.3)!important;
  border-radius:50%!important;box-shadow:none!important;
  display:flex!important;align-items:center;justify-content:center;flex:none;
  color:#7ff2f2!important;opacity:1!important}
.ofelt-back #fsbtn svg{width:60%;height:60%}
.ofelt-back #fsbtnhint-float{position:static!important;left:auto!important;right:auto!important;
  bottom:auto!important;top:auto!important;margin:0!important;padding:0!important;
  background:none!important;border:none!important;box-shadow:none!important;
  font:800 calc(var(--fchipF,16px) * .72)/1 Cairo,sans-serif!important;
  color:#7ff2f2!important;white-space:nowrap;display:flex!important;align-items:center}

.ofelt-round{left:50%;transform:translateX(-50%);top:var(--fpad,10px);
  width:var(--froundW,188px);height:var(--froundH,64px);flex-direction:column;gap:3px}
.ofelt-round .l{font:700 var(--flblF,12px)/1.3 Cairo,sans-serif;color:var(--fmut)}
.ofelt-round .v{font:800 var(--froundF,21px)/1 Cairo,sans-serif;color:var(--fink);
  text-shadow:0 0 12px rgba(69,237,237,.45);font-variant-numeric:tabular-nums}

/* THE STOPWATCH, standing on the felt. It used to float bare over the table with
   the round plate crowding it from one side; the plate has moved to the players
   panel, so the clock takes that room — a plate of its own, sunk into the table,
   and digits large enough to read from across the screen. */
.ofelt-clock{z-index:20;position:absolute;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:4px;pointer-events:none;box-sizing:border-box;
  /* ONE number decides the clock. --fclockF is what the painter wants; --fclockE
     is what the column can actually hold. The digits AND the padding must both
     read the same one — capping only the font left the padding on the larger
     value, so the box still outgrew the column it was told to fit inside. */
  --fclockE:min(var(--fclockF,32px),calc(var(--hudCol,120px) / 6.4));
  padding:calc(var(--fclockE) * .2) calc(var(--fclockE) * .5);border-radius:14px;
  background:linear-gradient(180deg,rgba(9,20,26,.62),rgba(4,11,15,.5));
  border:1px solid rgba(150,220,230,.2);
  box-shadow:inset 0 1px 0 rgba(210,240,248,.14),0 10px 26px rgba(0,0,0,.45)}
/* THE CLOCK MAY NEVER OUTGROW ITS COLUMN.
   The digits were sized from --fclockF alone while the box is forced to
   --hudCol, so on a wide screen the two disagreed and the time bled off the
   left edge — the owner photographed «00:09:25» sliced open at x=0 on a desktop.
   Eight tabular digits plus this rule's own padding need about 6.4em, so the
   font is capped at a sixth of the column and the clock fits at every width by
   construction rather than by luck. The label follows it down so the two never
   argue about which is bigger. */
.ofelt-clock{max-width:100%;overflow:hidden}
.ofelt-clock .l{font:700 min(var(--flblF,11px),calc(var(--hudCol,120px) / 11))/1.4 Cairo,sans-serif;
  color:var(--fmut);white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.ofelt-clock .d{font:900 var(--fclockE,var(--fclockF,32px))/1.15 Cairo,sans-serif;color:#f4feff;letter-spacing:.5px;
  font-variant-numeric:tabular-nums;
  text-shadow:0 0 4px rgba(255,255,255,.8),0 0 12px var(--fclock),0 0 26px var(--fclock);
  opacity:calc(.55 + .45 * var(--fblink))}

/* ======================================================================== */
/*  THE STATUS LINE and THE WORD BAR                                        */
/* ======================================================================== */
/* A CUE, NOT A BANNER. It ran the full width of the word bar in a bordered
   slab — the owner: "the tooltip should be smaller, not taking a lot of space
   on the table." It says its line in a pill exactly as wide as the words. */
body.ot-felt .arena-cen > .instr{position:absolute;left:var(--fbarCx,50%);transform:translateX(-50%);
  top:var(--fstatusTop,560px);width:max-content;max-width:calc(100% - 24px);
  text-align:center;z-index:11;padding:4px 16px;border-radius:999px;margin:0;
  background:rgba(4,13,18,.55);border:1px solid rgba(150,220,230,.2);
  box-shadow:0 6px 16px rgba(0,0,0,.4);
  font:800 var(--fstatusF,13px)/1.25 Cairo,sans-serif;color:var(--fink)}
body.ot-felt .arena-cen > .instr b{color:var(--fgold);font-weight:800}
body.ot-felt .arena-cen > .instr .rn{color:var(--fink)}

/* Centred on the TABLE, not on the screen: the rail owns the right quarter, and
   a bar centred on the window ran underneath it. */
body.ot-felt .racebar{position:absolute;left:var(--fbarCx,50%);transform:translateX(-50%);
  bottom:var(--fbarBottom,172px);width:var(--fbarW,660px);max-width:calc(100% - 24px);
  border-radius:16px;background:rgba(5,15,20,.43);border:1px solid rgba(150,220,230,.25);
  box-shadow:0 16px 40px rgba(0,0,0,.5);padding:10px 12px 12px;box-sizing:border-box;z-index:11;
  display:flex;align-items:stretch;gap:10px;margin:0}
body.ot-felt .racebar #win{flex:1;min-width:0;height:var(--fbarH,52px);border-radius:12px;box-sizing:border-box;
  border:1px solid rgba(200,214,222,.45);
  background:linear-gradient(180deg,rgba(4,12,17,.95),rgba(9,22,28,.9));
  box-shadow:inset 0 2px 10px rgba(0,0,0,.6);padding:0 16px;
  font:700 var(--fwordF,17px)/1 Cairo,sans-serif;color:var(--fink)}
body.ot-felt .racebar #win::placeholder{color:rgba(214,240,246,.42);font-weight:600}
/* the design frames its confirm button in polished steel */
body.ot-felt .racebar .btn{flex:none;height:calc(var(--fbarH,52px));padding:0 16px;border-radius:13px;
  border:0;background:var(--fmetal);box-shadow:none;
  display:flex;align-items:center;justify-content:center;
  font:800 var(--fbtnF,14px)/1 Cairo,sans-serif;color:#eafcff;white-space:nowrap;cursor:pointer;
  position:relative;isolation:isolate}
body.ot-felt .racebar .btn::before{content:'';position:absolute;inset:3px;border-radius:10px;z-index:-1;
  background:linear-gradient(180deg,#1b262e,#0d151b);border:1px solid rgba(150,220,230,.25)}
body.ot-felt .racebar .btn:disabled{opacity:.5;cursor:default}
body.ot-felt .racebar .btn.ghost{--fbtnF:13px}
body.ot-felt .racebar.locked{justify-content:center;align-items:center}
body.ot-felt .racebar .lockedw{font:800 var(--fwordF,17px)/1 Cairo,sans-serif;color:var(--fgold)}
body.ot-felt .racebar .lockedt{font:700 12px/1 Cairo,sans-serif;color:var(--fmut);margin-inline-start:10px}

/* ======================================================================== */
/*  THE LEADERBOARD — the design's banner rail                              */
/* ======================================================================== */
.ofelt-lb{position:absolute;z-index:13;display:flex;flex-direction:column;
  width:var(--lbW,408px);
  filter:drop-shadow(0 22px 44px rgba(0,0,0,.65)) drop-shadow(0 0 26px rgba(69,237,237,.13))}
.ofelt-lbin{position:absolute;inset:0;display:flex;flex-direction:column;
  /* THE PANEL IS THE WHOLE RIGHT SIDE now — flush with the screen's top, right
     and bottom — so only its INNER corners are cut; a cut against the screen
     edge just showed triangles of backdrop. */
  clip-path:polygon(18px 0,100% 0,100% 100%,18px 100%,0 calc(100% - 18px),0 18px);
  border-inline-start:1px solid rgba(150,220,230,.16);
  /* GLASS AT THE OWNER'S NUMBER: "20 or 35 percent transparent so we can see
     the effect of the table when it's glowing." About 70% opaque, evenly, top
     to bottom — solid enough to read twelve rows against, open enough that the
     felt's neon breathes through it. Alpha per stop, never opacity on the box:
     the banners inside must stay fully opaque. */
  background:
    repeating-linear-gradient(45deg,rgba(255,255,255,.016) 0 3px,rgba(0,0,0,0) 3px 6px),
    linear-gradient(180deg,rgba(16,27,34,.74) 0%,rgba(11,20,26,.68) 50%,rgba(8,15,20,.62) 100%),
    radial-gradient(120% 55% at 50% 0%,rgba(40,60,72,.4),rgba(0,0,0,0) 62%);
  backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px)}
/* THE TWO STACK AND CENTRE. They used to sit at opposite ends of the bar with a
   spacer between them — the title at one edge, the count at the other — which
   read as two separate things. They are one thing: who is at the table, and how
   many of them. Title above, count beneath, both on the panel's centre line. */
.ofelt-lbhd{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:calc(var(--lbhP,11px) * .42);
  padding:var(--lbhP,11px) var(--lbP,16px) calc(var(--lbhP,11px) - 1px);
  border-bottom:1px solid rgba(150,220,230,.22);
  background:linear-gradient(180deg,rgba(74,84,93,.5),rgba(18,26,32,.15))}
.ofelt-lbhd .t{flex:none;font:900 var(--lbhF,20px)/1 Cairo,sans-serif;color:var(--fink);
  text-shadow:0 0 14px rgba(69,237,237,.4);text-align:center}
.ofelt-lbhd .s{display:none}   /* the spacer that used to push them apart */
/* the count and the round share the second line of the same plate */
.ofelt-lbhd .hrow{display:flex;align-items:center;justify-content:center;gap:7px;flex-wrap:wrap}
.ofelt-lbhd .p.rd{color:var(--fink);border-color:rgba(120,214,226,.45);gap:5px}
.ofelt-lbhd .p.rd b{font:900 calc(var(--lbpF,12px) * 1.18)/1 Cairo,sans-serif;color:var(--fink);
  font-variant-numeric:tabular-nums;text-shadow:0 0 10px rgba(69,237,237,.45)}
.ofelt-lbhd .p{flex:none;display:flex;align-items:center;gap:7px;padding:5px 12px;border-radius:999px;
  border:1px solid rgba(120,214,226,.35);background:rgba(6,16,21,.75);
  font:700 var(--lbpF,12px)/1 Cairo,sans-serif;color:#bfe6ec;white-space:nowrap}
.ofelt-lbhd .p i{width:8px;height:8px;border-radius:50%;background:#3ee87f;box-shadow:0 0 8px #3ee87f;flex:none}
/* THE ROWS SCROLL, THEY DO NOT SQUASH.
   `overflow:hidden` here plus `flex:1;min-height:0` on the row below told
   flexbox it was free to shrink a row to nothing — and a row has NO intrinsic
   height to push back with, because everything drawn on it lives inside
   .ofelt-fr, which is position:absolute. So a rail with more rows than room
   slid its boxes under their own contents: text clipped mid-glyph, and the rank
   (the one part outside the plate's clip) landed in the gap on the row beneath.
   felt.js now sizes the row from the floors its contents actually keep; the row
   TAKES that height and flexbox may not take it back, and a rail that genuinely
   cannot seat everyone scrolls instead of stacking them on each other. */
.ofelt-rows{flex:1;min-height:0;display:flex;flex-direction:column;
  overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  scrollbar-width:none;-ms-overflow-style:none;
  gap:var(--lbGap,10px);padding:10px var(--lbP,12px) 12px}
.ofelt-rows::-webkit-scrollbar{width:0;height:0}
/* a rail with more players than it can show says so, softly, at its foot */
.ofelt-lb.scroll .ofelt-rows{
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 22px),rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 22px),rgba(0,0,0,0) 100%)}

.ofelt-row{flex:0 0 auto;height:var(--rowH,53px);position:relative;z-index:1}
/* STILL, at the owner's word: "remove the motions in the players panel."
   The leader keeps a fixed glow instead of a breathing one. */
.ofelt-row.r1{z-index:2;filter:drop-shadow(0 0 6px rgba(240,196,79,.32))}
/* THE BANNER DISSOLVES AT ITS FAR END — but only just. The rank used to float
   over an 18% melt at the far end; the owner moved it to the reading edge and
   put the SCORE at the far end instead («الترتيب يمين، النقاط أقصى اليسار»).
   A chip can't sit in a dissolve, so the melt is now a 14px edge-soften past
   the score — the plate still ends without a hard line, and the chip stays
   solid to its last pixel. */
.ofelt-fr{--fadeAt:calc(100% - 14px);
  -webkit-mask-image:linear-gradient(to right,#000 0%,#000 var(--fadeAt),rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(to right,#000 0%,#000 var(--fadeAt),rgba(0,0,0,0) 100%);
  position:absolute;inset:0;box-sizing:border-box;padding:var(--lbEdge,2px);
  clip-path:polygon(var(--cut,15px) 0,calc(100% - var(--cut,15px)) 0,100% var(--cut,15px),100% calc(100% - var(--cut,15px)),calc(100% - var(--cut,15px)) 100%,var(--cut,15px) 100%,0 calc(100% - var(--cut,15px)),0 var(--cut,15px));
  background:linear-gradient(160deg,#aab4bc,#545f68 40%,#8b959e 70%,#47525b)}
.ofelt-row.r1 .ofelt-fr{background:linear-gradient(160deg,#8a6420,#f0c04f 45%,#8a6420);padding:calc(var(--lbEdge,2px) + .5px)}
.ofelt-row.r2 .ofelt-fr{background:linear-gradient(160deg,#5f707e,#c9d8e4 45%,#5f707e);padding:calc(var(--lbEdge,2px) + .5px)}
.ofelt-row.r3 .ofelt-fr{background:linear-gradient(160deg,#6e431c,#cf9058 45%,#6e431c);padding:calc(var(--lbEdge,2px) + .5px);
  animation:gr-ember 4.6s ease-in-out infinite}
.ofelt-row.me .ofelt-fr{background:linear-gradient(160deg,#45eded,#1b6d74 45%,#45eded)}
.ofelt-row.me.r4plus .ofelt-fr{filter:drop-shadow(0 0 9px rgba(69,237,237,.47))}
/* the rank floats at the READING edge now (owner's order: rank right in Arabic,
   score far left, the name between them) — so the reservation moved with it:
   the reading side clears the rank's width, the far end keeps only its own
   padding and the score chip sits flush against the soft edge */
.ofelt-in{position:relative;height:100%;box-sizing:border-box;display:flex;align-items:center;
  gap:var(--lbInGap,9px);padding:0 10px;
  padding-inline-start:calc(8px + var(--rkW,48px));padding-inline-end:var(--lbEndP,14px);
  clip-path:polygon(var(--cut2,14px) 0,calc(100% - var(--cut2,14px)) 0,100% var(--cut2,14px),100% calc(100% - var(--cut2,14px)),calc(100% - var(--cut2,14px)) 100%,var(--cut2,14px) 100%,0 calc(100% - var(--cut2,14px)),0 var(--cut2,14px));
  background:linear-gradient(90deg,rgba(9,17,22,0) 0% 25%,rgba(9,17,22,1) 36% 100%)}
.ofelt-row.me .ofelt-in{background:linear-gradient(90deg,rgba(8,22,27,0) 0% 25%,rgba(8,22,27,1) 36% 100%)}
.ofelt-row.r2 .ofelt-in{/* motion removed */}

/* THE READING SIDE GETS ITS DARK. The name and the state line sit exactly where
   the bled face is brightest, which is why they were hard to pick out. These two
   layers go between the portrait and the text — ::before is the player's own
   colour under the wash, ::after is the dark above it — so the side you read from
   is a dark, tinted backing and the name and «what they are doing right now»
   stand off it. Both fade out before the points, and both are pinned to the
   READING start: the right in Arabic, the left in English.
   The z-order is the whole trick: ::before is generated first so it lands under
   the face, ::after last so it lands over it, and the content at z-index 1 sits
   above them both without a single number changing. */
.ofelt-in::before,.ofelt-in::after{content:'';position:absolute;inset:0;z-index:0;pointer-events:none}
.ofelt-in::before{opacity:.32;
  background:linear-gradient(to right,var(--rc,#45eded) 0%,rgba(0,0,0,0) 58%)}
.ofelt-in::after{background:linear-gradient(to right,
  rgba(5,11,15,.88) 0%,rgba(5,11,15,.8) 40%,rgba(5,11,15,.34) 68%,rgba(5,11,15,0) 88%)}
body.ar .ofelt-in::before{
  background:linear-gradient(to left,var(--rc,#45eded) 0%,rgba(0,0,0,0) 58%)}
body.ar .ofelt-in::after{background:linear-gradient(to left,
  rgba(5,11,15,.88) 0%,rgba(5,11,15,.8) 40%,rgba(5,11,15,.34) 68%,rgba(5,11,15,0) 88%)}

/* the player's own face, bled across the banner and faded into it */
/* Held back to a wash. At full strength this is a 55px band cut out of a 424px-tall
   crop — a forehead, blown up and blurred across the plate — and it read as the
   avatar rather than as the atmosphere behind it. The portrait tile below is the
   avatar now; this is the colour it throws. */
/* Brighter than it was. It had to be held down to .46 while it was a blown-up
   crop of a shoulder — a smear that loud would fight the name. Now that it is a
   whole character it can be seen. */
.ofelt-face{position:absolute;inset:0;z-index:0;overflow:hidden;opacity:.72;
  -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0% 27%,rgba(0,0,0,.65) 40%,#000 50% 68%,rgba(0,0,0,.55) 84%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0% 27%,rgba(0,0,0,.65) 40%,#000 50% 68%,rgba(0,0,0,.55) 84%,rgba(0,0,0,0) 100%)}
/* ARABIC RUNS THE OTHER WAY. Every gradient on this plate is written 90deg —
   left to right — but the banner's content is RTL, so the face bled in at the
   "start" landed in the middle and the plate's clear edge ended up behind the
   rank instead of behind the portrait. Mirror the three of them. */
body.ar .ofelt-face{
  -webkit-mask-image:linear-gradient(270deg,rgba(0,0,0,0) 0% 27%,rgba(0,0,0,.65) 40%,#000 50% 68%,rgba(0,0,0,.55) 84%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(270deg,rgba(0,0,0,0) 0% 27%,rgba(0,0,0,.65) 40%,#000 50% 68%,rgba(0,0,0,.55) 84%,rgba(0,0,0,0) 100%)}
/* THE WHOLE CHARACTER, NOT A CROP OF ONE. This was `cover`, and cover on a 220x220
   portrait inside a 385x49 banner scales the picture to 385 wide — 385 TALL — and
   shows a 49px band of it. That band was a shoulder: a smear nobody could name.
   `contain` fits the art to the banner's HEIGHT instead, so the character is whole,
   and it is anchored just off the reading edge — behind the name, in the room the
   banner actually has. Small, but a robot rather than a blur. */
.ofelt-face .sav{display:block;position:absolute;inset:0}
/* THE EYES, IN CLOSE-UP. `cover` on a 220x220 portrait inside a 385x42 banner
   renders the art 385 tall and shows a 42px band of it — about a ninth of the
   picture. That extreme crop is the enemy only while it is pointed at nothing;
   aimed at the eyes it is exactly the shot the owner asked for.

   33% is solved, not guessed. The avatars are consistently framed busts and their
   eyes sit at 33-38% of the image height (measured on fire.png and ninja.png).
   With cover, the band's offset is (scaledH - boxH) x Y%, so for the band's CENTRE
   to land on the eye line: (385-42) x Y + 21 = 0.35 x 385  ->  Y = 33%.
   Point it at 26% instead — where it used to be — and you frame a forehead. */
.ofelt-face .sav img,.ofelt-face .sav svg,.ofelt-face video{
  display:block;width:100%;height:100%;object-fit:cover;object-position:50% 33%;
  filter:saturate(1.22) contrast(1.14)}
/* the player's own accent, washed behind their face. The design wrote this as
   `var(--rc)30` — a hex alpha glued onto a variable, which CSS does not parse
   at all; the wash is carried by opacity here instead. */
/* the player's colour thrown behind the eye line, so the close-up has something
   to stand off instead of sitting flat on the plate */
.ofelt-face .glow{position:absolute;inset:0;opacity:.3;
  background:radial-gradient(52% 150% at 50% 50%,var(--rc,#45eded),rgba(0,0,0,0) 72%)}
.ofelt-face .glow::after{content:'';position:absolute;inset:0;opacity:.7;
  background:radial-gradient(30% 44% at 50% 44%,rgba(230,245,248,.2),rgba(0,0,0,0) 70%)}
.ofelt-face .fade{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(10,18,23,0) 0% 34%,rgba(10,18,23,.1) 44% 74%,rgba(10,18,23,.45) 100%)}
body.ar .ofelt-face .fade{
  background:linear-gradient(270deg,rgba(10,18,23,0) 0% 34%,rgba(10,18,23,.1) 44% 74%,rgba(10,18,23,.45) 100%)}
body.ar .ofelt-fr{
  -webkit-mask-image:linear-gradient(to left,#000 0%,#000 var(--fadeAt),rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(to left,#000 0%,#000 var(--fadeAt),rgba(0,0,0,0) 100%)}
body.ar .ofelt-in{background:linear-gradient(270deg,rgba(9,17,22,0) 0% 25%,rgba(9,17,22,1) 36% 100%)}
body.ar .ofelt-row.me .ofelt-in{background:linear-gradient(270deg,rgba(8,22,27,0) 0% 25%,rgba(8,22,27,1) 36% 100%)}

/* THE PORTRAIT. The face above is bled across the whole banner and cropped by it:
   the art is 220x220 and the plate is 424x55, so `cover` scales the picture to
   424 wide — 424 TALL — and the banner shows a 55px band of it. That band is a
   forehead, which is why the characters could not be told apart. This tile shows
   the whole portrait beside the wash, ringed in the player's own colour. */
.ofelt-av{position:relative;z-index:1;flex:none;
  width:var(--avT,40px);height:var(--avT,40px);border-radius:calc(var(--avT,40px) * .24);
  overflow:hidden;box-sizing:border-box;border:1.5px solid var(--rc,#45eded);
  box-shadow:0 0 9px -1px var(--rc,#45eded),inset 0 1px 0 rgba(255,255,255,.16);
  background:linear-gradient(180deg,#16303a,#08181f)}
.ofelt-av .sav,.ofelt-av img,.ofelt-av svg,.ofelt-av video{display:block;
  width:100%;height:100%;object-fit:cover;object-position:50% 50%}
/* the first three wear their metal on the portrait too */
.ofelt-row.r1 .ofelt-av{border-color:#f0c04f;box-shadow:0 0 12px -1px rgba(240,196,79,.85),inset 0 1px 0 rgba(255,255,255,.2)}
.ofelt-row.r2 .ofelt-av{border-color:#dde7ee;box-shadow:0 0 10px -1px rgba(210,228,240,.7),inset 0 1px 0 rgba(255,255,255,.2)}
.ofelt-row.r3 .ofelt-av{border-color:#d0925a;box-shadow:0 0 10px -1px rgba(208,146,90,.7),inset 0 1px 0 rgba(255,255,255,.2)}
/* a banner too short to seat a portrait drops it rather than squashing it */
.ofelt-lb.dense .ofelt-av{display:none}

.ofelt-id{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;position:relative;z-index:1}
/* unicode-bidi:plaintext + the <bdi> wrapper: a Latin name on the Arabic rail
   was ellipsized at its START («…aitical2») — clipped and backwards, as the
   owner put it. Each name now lays out in its own script's direction and
   trims at its own logical end. */
.ofelt-nm{font:800 var(--lbnF,15px)/1.5 Cairo,sans-serif;color:var(--fink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
  unicode-bidi:plaintext;
  text-shadow:0 1px 3px rgba(0,0,0,.9)}
/* A NAME MAY BE SHORTENED, NOT ERASED (owner's phone video, 2026-08-06: «في جهة
   اليمين أسماء اللاعبين مقطوعة» — the rail read «ku…», «…يس», «…س»). The name
   shares a min-width:0 column with the status line and the score chip, and a
   flex item with no floor yields ALL of its width to its neighbours: measured at
   844x390, «سايبرنوت» was given a 31px box inside a 115px row. The floor makes
   the ellipsis mean something — under about four characters there is nothing
   left to recognise a player by, and the status word beside it trims itself
   already (see .ofelt-st below), so the width comes from the box that can
   actually spare it. */
.ofelt-nm{min-width:4.4em}
/* THE STATE LINE TRIMS ITSELF. It is white-space:nowrap and it sits in the same
   min-width:0 column as the name — but it had no overflow of its own, and its
   <u> is a flex item, whose AUTOMATIC minimum is its own min-content. Neither
   box could shrink and neither box clipped, so a state word wider than the name
   column did not ellipsize: it ran straight out of the column and painted across
   the portrait and the score chip. «لم يُلقِ بعد» over a 0 — the collision in the
   owner's photograph. The word gives now, the same way the name above it does. */
.ofelt-st{display:flex;align-items:center;gap:5px;font:700 var(--lbsF,10.5px)/1 Cairo,sans-serif;
  color:#7fe0a0;white-space:nowrap;min-width:0;max-width:100%;overflow:hidden}
.ofelt-st u{text-decoration:none;min-width:0;overflow:hidden;text-overflow:ellipsis}
.ofelt-st i{width:7px;height:7px;border-radius:50%;background:#3ee87f;box-shadow:0 0 7px #3ee87f;flex:none}
/* a rail packed tight enough that the state WORDS would only crowd the name
   drops the words but KEEPS THE DOT (owner, 2026-08-01: on his phone he could
   no longer tell who was thinking, who had thrown, who had locked in — the
   dot is that answer at a glance: green = done, amber blinking = still at it) */
.ofelt-lb.dense .ofelt-st{display:flex}
.ofelt-lb.dense .ofelt-st u{display:none}
/* the compact rail spends its pixels on the NAME: the score keeps its number,
   the «نقطة/pts» unit goes, and the box tightens around the digits */
.ofelt-lb.dense .ofelt-pts s{display:none}
.ofelt-lb.dense .ofelt-pts{padding:3px 5px}
.ofelt-lb.dense .ofelt-st i{width:8px;height:8px}
/* FOLDING IS A LAST RESORT, AND IT IS ABOUT HEIGHT — NOT WIDTH.
   A rail with no vertical room for two stacked text lines per row moves the
   state ONTO the name's line rather than dropping it, because the state is the
   one thing the owner said he could not do without («ما اقدر اشوف ايش قاعد
   يسوون»). But sharing a line costs the name ~13px of column, and on a 126px
   rail that is what pushed سايبرنوت to the 10px floor where Arabic loses its
   dots. So this is keyed on .fold — set only when full dress genuinely does not
   fit — and NOT on .dense, which merely means the rail is narrow. A narrow rail
   with three players has room to spare and keeps the name on its own line. */
.ofelt-lb.fold .ofelt-id{flex-direction:row;align-items:center;gap:5px}
/* …and the name keeps a FLOOR even here. min-width:0 is what let the shrink
   factors below be argued away entirely: 100-against-1 only decides who gives
   first, not when giving stops, so on a 115px row «سايبرنوت» still ended up in a
   31px box — the owner's «أسماء اللاعبين مقطوعة». The state word trims itself
   (.ofelt-st, above) and yields before this does. */
.ofelt-lb.fold .ofelt-nm{flex:1 1 auto;min-width:4.4em}
/* the shrink factors are the whole rule: sharing one line evenly would have cost
   the name half its letters. At 100 against 1 the state word spends every letter
   it has before the name spends one — but never the DOT, which is the answer at
   a glance (green = done, amber blinking = still at it) and so is the state's
   own floor. */
.ofelt-lb.fold .ofelt-st{flex:0 100 auto;min-width:8px}
.ofelt-st.wait{color:#f0c04f}
.ofelt-st.wait i{background:#f0c04f;box-shadow:0 0 7px #f0c04f;animation:ofeltStw 1.05s ease-in-out infinite alternate}
@keyframes ofeltStw{from{opacity:1}to{opacity:.35}}

.ofelt-pts{position:relative;z-index:1;flex:none;min-width:var(--lbptW,60px);display:flex;
  flex-direction:column;align-items:center;gap:2px;padding:5px 9px;border-radius:7px;box-sizing:border-box;
  background:rgba(3,9,12,.95);border:1px solid rgba(160,230,240,.45);
  box-shadow:inset 0 0 10px rgba(0,0,0,.55),0 0 10px rgba(69,237,237,.14)}
.ofelt-pts b{font:900 var(--lbvF,20px)/1 Cairo,sans-serif;color:#fff;letter-spacing:.5px;
  font-variant-numeric:tabular-nums}
.ofelt-pts s{text-decoration:none;font:700 var(--lbuF,10px)/1 Cairo,sans-serif;color:#9fd6de}

/* lifted out of the plate and pinned to the banner's READING edge — the first
   thing the eye meets on each row is the place (owner's order: rank on the
   right in Arabic, mirrored to the left in English). */
/* NO PLATE. The number is the thing — the metal chip it used to sit on is gone,
   and the place is told by the colour of the digit and the neon it carries.
   Gold, silver and bronze for the first three; everyone from fourth down is white
   with barely any glow at all, so the top of the list is the only part that
   shines. */
.ofelt-rk{position:absolute;inset-inline-start:calc(var(--lbP,12px) * .45);top:50%;
  transform:translateY(-50%);z-index:4;width:var(--rkW,48px);height:var(--rkH,38px);
  display:flex;align-items:center;justify-content:center;
  box-sizing:border-box;background:none;filter:none}
.ofelt-rk > b{display:flex;align-items:center;justify-content:center;
  font:900 calc(var(--rkF,18px) * 1.22)/1 Cairo,sans-serif;font-variant-numeric:tabular-nums;
  color:#eaf4f5;text-shadow:0 0 5px rgba(226,240,246,.28),0 1px 2px rgba(0,0,0,.6)}
.ofelt-row.r1 .ofelt-rk > b{color:#f6cd5e;
  text-shadow:0 0 8px rgba(240,196,79,.85),0 0 18px rgba(240,196,79,.45),0 1px 2px rgba(0,0,0,.55)}
.ofelt-row.r2 .ofelt-rk > b{color:#dde7ee;
  text-shadow:0 0 8px rgba(214,232,244,.8),0 0 16px rgba(214,232,244,.38),0 1px 2px rgba(0,0,0,.55)}
.ofelt-row.r3 .ofelt-rk > b{color:#d0925a;
  text-shadow:0 0 8px rgba(208,146,90,.8),0 0 16px rgba(208,146,90,.36),0 1px 2px rgba(0,0,0,.55)}

/* the neon spine that says which row is yours */
.ofelt-mebar{position:absolute;right:0;top:0;bottom:0;width:3.5px;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(69,237,237,.15),var(--fneon) 50%,rgba(69,237,237,.15));
  box-shadow:0 0 9px rgba(69,237,237,.67)}
/* POINTS AT THE PANEL, and the direction lives in the SHAPE. It used to live
   in an inline scaleX(-1) — which gr-point's own transform keyframes replaced
   on frame one, so the arrow spent its life pointing off-screen. The owner
   caught it: "it was pointing outward, it should point inward." */
.ofelt-arrow{position:absolute;width:15px;height:18px;z-index:14;pointer-events:none;
  clip-path:polygon(0 0,0 100%,100% 50%);background:var(--fneon);
  filter:drop-shadow(0 0 6px var(--fneon)) drop-shadow(0 0 14px rgba(69,237,237,.53));
  opacity:.95}

/* the leader's sparks */
.ofelt-fx{display:none}   /* the leader's rising sparks — retired with the rail's motions */
.ofelt-fx span{position:absolute;bottom:26px;border-radius:50%;opacity:0;
  background:radial-gradient(circle,#fff2c0 0%,#f0c04f 55%,rgba(240,192,79,0) 100%);
  box-shadow:0 0 6px rgba(255,220,120,.9);animation:gr-part linear infinite}

/* ---- the design's keyframes, verbatim --------------------------------- */
@keyframes gr-part{0%{transform:translateY(6px) scale(.5);opacity:0}12%{opacity:1}78%{opacity:.85}100%{transform:translateY(-78px) scale(1.1);opacity:0}}
@keyframes gr-point{0%,100%{transform:translateX(0);opacity:.8}50%{transform:translateX(-6px);opacity:1}}
@keyframes gr-blink{0%,100%{opacity:1}50%{opacity:.4}}
@keyframes gr-aura{0%,100%{filter:drop-shadow(0 0 4px rgba(240,196,79,.25))}
  50%{filter:drop-shadow(0 0 9px rgba(255,222,125,.45)) drop-shadow(0 4px 14px rgba(240,196,79,.28))}}
@keyframes gr-ember{0%,100%{filter:brightness(1)}32%{filter:brightness(1.14) drop-shadow(0 0 5px rgba(214,138,80,.3))}
  55%{filter:brightness(1.04)}76%{filter:brightness(1.11) drop-shadow(0 0 4px rgba(214,138,80,.22))}}
@keyframes gr-glowIn{0%,100%{box-shadow:inset 0 0 8px rgba(205,228,244,.18)}
  50%{box-shadow:inset 0 0 24px rgba(225,244,255,.55),inset 0 0 44px rgba(180,210,230,.25)}}

/* ---- the fullscreen chip the design draws bottom-right ----------------- */
body.ot-felt #fsbtn,body.ot-felt #fsbtnhint-float{z-index:24}

/* A phone lying down cannot afford the header band OR the status line above
   the bar; the design's own furniture is what stays. */
body.ot-felt.ot-tight .ofelt-round{display:none}
body.ot-felt.ot-tight .arena-cen > .instr{display:none}
body.ot-felt.ot-tight .ofelt-lbhd{display:none}

/* NO prefers-reduced-motion block here, deliberately. There was one, and it took
   the first three banners' whole reward with it — the leader's gold aura, second's
   glow, third's ember and the winner's sparks all switched off on any machine with
   the OS setting on, which is what "there were some effects, I cannot see them"
   turned out to be. The lit socket lost its pulse the same way. Slow ambient
   motion only; nothing here flashes. */

/* ======================================================================== */
/*  HOW TO PLAY — readable, on the final screen's glass                     */
/*  The owner: "even on my wide screen I cannot read it properly — make it  */
/*  professional, with the transparent background we used for the trophy."  */
/*  Page-wide overrides of howto.js's bundled sizes; this file only loads   */
/*  on the Overtake pages, so Blitz and Hunt keep their own overlay.        */
/* ======================================================================== */
.ht-card{max-width:820px!important;padding:26px 30px!important;
  background:rgba(13,20,27,.66)!important;border:1px solid rgba(255,255,255,.12)!important;
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:20px!important}
.ht-kick{font-size:12px!important;letter-spacing:2px!important}
.ht-st{font-size:26px!important;margin-bottom:10px!important}
.ht-sd{font-size:17px!important;line-height:1.75!important;color:#cfe0e6!important;min-height:0!important}
.ht-steppill{font-size:15px!important}
.ht-steppill b{min-width:27px!important;height:27px!important;font-size:14px!important}
.ht-btn{font-size:17px!important;padding:14px!important}
.ht-dsa{font-size:14px!important}
.ht-stage{flex-basis:220px!important;width:220px!important}
@media(max-width:640px){
  .ht-card{padding:18px!important}
  .ht-st{font-size:21px!important}
  .ht-sd{font-size:15px!important;line-height:1.65!important}
  .ht-stage{width:100%!important;flex-basis:auto!important}}

/* ---- PHONES DO NOT PAY FOR GLASS ----------------------------------------
   The full-height rail carries a backdrop blur — on a phone that is a
   full-screen GPU blur pass on every frame, and it is a large part of the
   "slowness" the owner keeps feeling. The tint alone reads the same at
   arm's length; the blur stays for monitors. */
@media (max-width:1024px){
  .ofelt-lbin{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
}

/* THE CURTAIN (see felt.js hold()): while a transient paint bail retries,
   the raw stage is held dark so the retired base design never flashes through.
   The felt layer lives on .frame, not in .stage, so a standing table survives. */
body.ot-hold .stage{visibility:hidden!important}

/* THE PANEL FOLDS AWAY (owner: an icon, a motion, and NOTHING resizes).
   The rail slides off the right edge; the solve is untouched, so the table,
   cards and hand hold exactly still and the rail's room reads as open felt. */
.ofelt-lb{transition:transform .38s cubic-bezier(.4,0,.2,1),opacity .38s ease}
body.ot-lbhide .ofelt-lb{transform:translateX(112%);opacity:0;pointer-events:none}
.ofelt-arrow{transition:opacity .38s ease}
body.ot-lbhide .ofelt-arrow{opacity:0!important}
.ofelt-lbtog{position:absolute;top:8px;right:160px;z-index:41;width:44px;height:44px;
  display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;
  color:#bfe6ec;border-radius:9px;border:1px solid rgba(255,255,255,.14);
  background:rgba(13,20,27,.62);-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);
  transition:right .38s cubic-bezier(.4,0,.2,1)}
.ofelt-lbtog:active{transform:scale(.93)}
body.ot-lbhide .ofelt-lbtog svg{transform:scaleX(-1)}
@media(max-width:1024px){.ofelt-lbtog{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(11,18,24,.85)}}

/* the table returns from the results with the same breath the results arrive
   with — a freshly built layer fades up instead of snapping in (the fast
   path keeps the standing layer, so mid-round repaints never re-run this) */
.ofelt{ animation:ofeltIn .26s ease-out }
@keyframes ofeltIn{ from{opacity:0} to{opacity:1} }

/* THE PAGE NEVER PANS. The table spills past every edge BY DESIGN, and the
   fan is wider than the screen — which handed the document a scrollable
   overflow, and on a touch screen the whole game PANNED under a swipe (the
   owner's tablet shots: the composition shoved half a screen sideways, the
   rim showing, «الطاولة تتحرك»). While a game screen is up the body clips
   its overflow and rubber-banding is off — the game is a viewport, not a
   document. Menus keep their own scrolling. */
/* overflow:clip, not hidden — hidden boxes are still scroll containers that
   focus and script can pan (measured: scrollTo landed at -500,200 with
   hidden). clip is not a scroll container at all. The clip lands on .frame
   and .stage — both exactly viewport-sized, so nothing visible is lost, and
   with the spill cut at its source the document has NOTHING left to scroll. */
body.ot-felt,body.ot-res,body.ot-fin{
  overflow:hidden!important;overflow:clip!important;
  overscroll-behavior:none;touch-action:manipulation}
body.ot-felt .frame,body.ot-felt .stage,
body.ot-res .frame,body.ot-res .stage,
body.ot-fin .frame,body.ot-fin .stage{
  overflow:hidden!important;overflow:clip!important}

/* ===== SELF-CONTAINED SKINS STAND ALONE (owner, 2026-08-01) =====
   A purchased skin (Arcane) is a complete SVG card; the felt's milled-steel
   dress must stand down for it or the two designs stack on one card. */
body.ot-felt .pool .pcard.arcane:not(.back),
body.ot-felt .hand .hcard.arcane,
body.ot-felt .pool .pcard.flame:not(.back),
body.ot-felt .hand .hcard.flame{
  background:none!important;border:0!important;box-shadow:none!important;color:inherit!important}

/* THE STATUS COMES BACK (owner 2026-08-02: «ما اقدر اشوف ايش قاعد يسوون»).
   Dense mode had dropped the state WORDS and kept only the dot, so a rival
   thinking, a rival who had thrown and a rival locked in all looked alike.
   The words return at a size the row can carry. */
.ofelt-lb.dense .ofelt-st u{display:inline;font-size:.86em;opacity:.95}
