/* =====================================================================
   COPPER — "Terminal" skin
   ---------------------------------------------------------------------
   Loaded LAST on every page (after responsive.css). The palette, font and
   2px radii are already baked into each page's own CSS; this layer adds
   the parts of design/cppr-mine-design.html that are not a token swap:
   uppercase wide-tracked labels, the faint scanline on panels, and the
   machine-room details. Rules that must beat CSS injected at runtime by
   header.js / chat.js are prefixed `html body` for specificity, so load
   order never decides who wins.
   ===================================================================== */

:root{
  --copper:#ff8a3d;
  --copper-lit:#ffb681;
  --copper-dim:rgba(255,138,61,0.13);
  --patina:#4fd6a5;
  /* corner radius: every border-radius in the site reads var(--r).
     Panels default to a soft 14px; controls become pills, counters circles. */
  --r:14px;
  --scan:repeating-linear-gradient(0deg, rgba(255,255,255,0.014) 0 1px, transparent 1px 3px);
}

/* mono is wider than the old sans — one notch down keeps every layout fitting */
/* 14px, not 13. The base size is inherited by the chips, the panels and
   everything that sizes the centre column, so dropping it a pixel shrank the
   whole column - the panels above the board got visibly smaller and the
   layout re-centred, opening a gap between the chat and the grid. The
   tabular figures are the part of this rule worth keeping. */
html, body{ font-size:14px; font-variant-numeric:tabular-nums; }
::selection{ background:rgba(255,138,61,0.35); color:#fff; }
:focus-visible{ outline:1px solid var(--copper); outline-offset:1px; }

/* ---------- header ---------- */
html body header .brand span{ letter-spacing:0.3em; font-weight:700; }
html body nav a{
  font-size:11px; font-weight:500; letter-spacing:0.14em; text-transform:uppercase;
}
html body .wchip.addr{ letter-spacing:0.08em; text-transform:uppercase; font-size:11.5px; }

/* ---------- panels: the scanline ---------- */
.card, .rewards, .chip, .stat, .winners, .rows,
.claim-card, .pos-card, .ps-card, .ps-block, .modal, .confirm,
.pcard, .activity, .me-stat,
.chart-card, .swap-card, .box,
.acc, .step, .rcard, .fair, .lode-card{
  background-image:var(--scan);
}

/* ---------- labels & section heads ---------- */
.rewards-head, .ps-title, .pos-head, .lb-head, .fc-headcol,
.modal-label, .lock-label, .pg-label, .c-title, .d-title{
  letter-spacing:0.14em; text-transform:uppercase;
}
.ps-title{ font-size:13px; font-weight:700; letter-spacing:0.18em; }
.acc-title{ letter-spacing:0.06em; }

/* ---------- buttons: uppercase, tracked ---------- */
.deploy, .ghost-btn, .seg button, .claims button, .cf-actions button,
button.action, .claim-btn, .cbtn, .flex-btn, .modal-actions button,
button.go, button.sell, button.maxb, button.tab, .pg-btn, .ctr-btn, .unit-seg button, .mode button,
html body .composer button, html body .pf-btn, html body .pf-save, html body .pf-cancel{
  text-transform:uppercase; letter-spacing:0.12em; font-size:11px; font-weight:600;
}
.deploy, .claim-btn, button.action{ letter-spacing:0.16em; font-weight:700; font-size:12px; }

/* the main call to action is bone-on-black, lit copper when armed */
.deploy:not(:disabled):hover, button.action:not(:disabled):hover{ filter:brightness(1.08); }

/* ---------- scrollbars ---------- */
*::-webkit-scrollbar{ width:6px; height:6px; }
*::-webkit-scrollbar-thumb{ background:#282828; border-radius:999px; }
*::-webkit-scrollbar-track{ background:transparent; }

/* inline links in prose (maintenance / beta pages had none styled) */
p a, .safe a, .foot a{ color:var(--copper); text-underline-offset:2px; }
p a:hover{ color:var(--copper-lit); }

/* ---------- shape: round, not square ----------
   Every radius in the site is var(--r) (tools/round_pass.py), so shape is
   decided here, per role. Setting --r on an element changes only that
   element's own corners; its children keep whatever their own rule says. */

/* controls: pills */
button, input, select, textarea,
nav a, .wchip, .pill, .res, .lb-pill, .rules-tag, .badge, .perm,
.mini, .toggle, .toggle .knob, .lastbar, .quick button, .seg, .unit-seg,
.bar, .share-bar, .share-fill, .furnace, .fc-track, .fc-fill,
.fresh-tag, .ps-tag, .lock-when, .dex-item, .note,
html body .composer input, html body .composer button{ --r:999px; }

/* counters and single glyphs: circles */
.mark, .step .n, .acc-n, .stepper button, .pg,
.cf-top img, html body .composer .emoji-btn, html body .chat-toggle{ --r:50%; }

/* bigger surfaces get a little more curve than the default */
.card, .rewards, .winners, .panel, .chart-card, .swap-card, .claim-card, .pos-card,
.ps-block, .modal, .confirm, .activity, .acc{ --r:18px; }

/* ---------- the mine grid: copper nuggets ----------
   Each block is a nugget: ::before is the dark face, clipped to the nugget's
   shape (traced from img/nugget.png); ::after is the copper wire outline
   itself. The block's own box is invisible, so a glow (drop-shadow) follows
   the nugget's edge instead of a square or circle. Four orientations are
   mixed across the board so it reads as ore, not wallpaper. */
:root{
  --nugget:polygon(55.8% 4.6%, 24.7% 19.6%, 16.7% 33.4%, 14.9% 39.8%, 8.9% 47.3%, 5.8% 58.2%, 18.7% 80.6%,
    31.7% 86.9%, 44.9% 95.4%, 57.9% 89.6%, 76.3% 87.2%, 90.0% 72.6%, 94.6% 60.4%, 87.7% 42.8%, 89.3% 29.2%,
    88.6% 27.3%, 81.5% 18.3%, 69.4% 14.0%);
}
html body .tile{
  position:relative; aspect-ratio:1/1; isolation:isolate;
  background:none !important; border:none !important; box-shadow:none !important; border-radius:0 !important;
  transition:transform .15s ease, filter .25s ease, opacity .2s ease;
}
html body .tile::before, html body .tile::after{
  content:''; position:absolute; inset:0; pointer-events:none; transform:var(--flip, none);
}
html body .tile::before{
  z-index:-1; clip-path:var(--nugget);
  background:radial-gradient(circle at 40% 35%, #161210, var(--surface-2) 70%);
  transition:background .25s ease;
}
html body .tile::after{
  z-index:1; background:url(/img/nugget.png?v=1) center / 100% 100% no-repeat;
  filter:grayscale(.7) brightness(.5); opacity:.9;   /* idle: dull, unpolished copper */
  transition:filter .25s ease, opacity .25s ease;
}
html body .tile > *{ position:relative; z-index:2; }
html body .tile:nth-child(4n+2){ --flip:scaleX(-1); }
html body .tile:nth-child(4n+3){ --flip:scaleY(-1); }
html body .tile:nth-child(4n){ --flip:scale(-1,-1); }

html body .tile:hover{ transform:translateY(-2px) scale(1.03); }
html body .tile:hover::after{ filter:grayscale(.4) brightness(.8); opacity:1; }

html body .tile.selected{ filter:drop-shadow(0 0 10px rgba(255,138,61,0.55)); }
html body .tile.selected::before{ background:radial-gradient(circle at 40% 35%, rgba(255,138,61,0.28), rgba(255,138,61,0.08) 70%), var(--surface-2); }
html body .tile.selected::after{ filter:none; opacity:1; }

/* the block being drawn, and the one that won: molten copper */
html body .tile.drawing, html body .tile.won{ filter:drop-shadow(0 0 16px rgba(255,138,61,0.85)); }
html body .tile.drawing::before, html body .tile.won::before{
  background:radial-gradient(circle at 38% 32%, #ffd3b0, var(--copper) 55%, #a8470f);
}
html body .tile.drawing::after, html body .tile.won::after{ filter:brightness(1.15); opacity:1; }
html body .tile.won{ transform:scale(1.06); }

/* The sweep steps as fast as 55ms, but these transitions ran 250ms.
   Of everything the reveal changes, the copper halo on the block itself
   (filter: none -> drop-shadow, above) is the one that actually
   interpolates - the nugget's brightness() and the ::before gradient are
   mismatched values and snap. So the halo faded in over 250ms while the
   cursor left after 55: early blocks showed about a fifth of the glow and
   looked dim, late ones (575ms steps) lit fully. 45ms completes inside
   even the fastest step, so every block looks the same, first to last. */
html body .tile{ transition:transform .15s ease, filter 45ms linear, opacity 45ms linear; }
html body .tile::before{ transition:background 45ms linear; }
html body .tile::after{ transition:filter 45ms linear, opacity 45ms linear; }
/* the landing is a separate, slower beat: 24 blocks dimming at once */
html body .tile.faded{ transition:opacity .3s ease, filter .3s ease; }

/* the About page's miniature board uses the same nuggets */
html body .mini-grid i{
  position:relative; background:none !important; border:none !important; box-shadow:none !important; border-radius:0 !important;
}
html body .mini-grid i::before, html body .mini-grid i::after{ content:''; position:absolute; inset:0; transform:var(--flip, none); }
html body .mini-grid i::before{ clip-path:var(--nugget); background:var(--surface-2); transition:background .35s ease; }
html body .mini-grid i::after{ background:url(/img/nugget.png?v=1) center / 100% 100% no-repeat; filter:grayscale(.7) brightness(.5); transition:filter .35s ease; }
html body .mini-grid i:nth-child(4n+2){ --flip:scaleX(-1); }
html body .mini-grid i:nth-child(4n+3){ --flip:scaleY(-1); }
html body .mini-grid i:nth-child(4n){ --flip:scale(-1,-1); }
html body .mini-grid i.on::before{ background:rgba(255,138,61,0.14); }
html body .mini-grid i.on::after{ filter:none; }
html body .mini-grid i.strike{ filter:drop-shadow(0 0 12px rgba(255,138,61,0.85)); }
html body .mini-grid i.strike::before{ background:radial-gradient(circle at 38% 32%, #ffd3b0, var(--copper) 55%, #a8470f); }
html body .mini-grid i.strike::after{ filter:brightness(1.15); }

/* drag-select: no text highlighting or page panning while painting blocks */
#tileGrid{ user-select:none; -webkit-user-select:none; touch-action:none; }
#tileGrid.dragging .tile{ cursor:crosshair; }

/* ---- close the dark space either side of the board ----
   The board was 812px inside a 1134px column, so ~320px sat empty beside it.
   Two changes, together:

   1. The board is wider. 163px is the largest tile where all five rows still
      fit on a 1080px-tall screen - measured: bottom row ends at 1078px, and
      175px tiles push it 58px below the fold.
   2. The column no longer has a width of its own, so it takes the board's
      867px and the panel row stretches to match. Previously .mid-col sized to
      its own TEXT, which is what let it drift when the restyle changed the
      fonts - pinning it to the board instead is stable either way.

   Recent Winners stays under the board, by choice. */
html.uniscale .tile{ width:163px !important; height:163px !important; }
html.uniscale .grid{ gap:13px !important; }
.left-wrap{ width:auto; }
.mid-col{ width:auto; }
.chips{ width:100%; }
.winners{ width:100% !important; }

/* The board cannot grow past 867px without pushing its bottom row off a
   1080px screen, so some of the leftover width goes to the chat and the rail.
   Not all of it - a gap beside the board is wanted.

   THE CHAT'S SLOT IS FIXED AT 360px, OPEN OR CLOSED.
   Collapsing used to shift the board, the panels, Recent Winners and the rail
   314px to the left, because the chat is a flex item and the width it gave up
   was handed to everything after it. The panel only *looks* narrow when
   collapsed; it still reserves its slot, so nothing else moves.

   320px of panel + 40px margin = 360. Collapsed: 46px of rail + 314 = 360.
   Keep those two pairs summing to the same number or the layout jumps again.

   Scoped to html.uniscale so the stacked phone/tablet layout is untouched -
   there the chat is a full-width block and must stay fluid. */
html.uniscale .tile{ width:163px !important; height:163px !important; }
html.uniscale .grid{ gap:13px !important; }
.left-wrap{ width:auto; }
.mid-col{ width:auto; }
.chips{ width:100%; }
.winners{ width:100% !important; }
.left-stack{ width:100%; }
html.uniscale .chat{ flex:0 0 320px !important; max-width:320px !important; margin-right:40px; }
html.uniscale .right{ flex:1 1 auto; max-width:480px; }
/* chat.js collapses with width:46px !important. A flex item that GROWS treats
   width as a base size and expands past it, so the collapsed rail grew back -
   it has to opt out of growing, not just be given a width. */
html.uniscale .chat.collapsed{ flex:0 0 46px !important; max-width:46px !important; margin-right:314px; }

/* Icon images ship with NO src - every page script fills them in from
   cppr-assets.js. Until that runs, Chrome paints its broken-image glyph, and
   on a cold pane load that is very visible because ethers (526KB) parses
   first: switching to Stake after a refresh flashed 17 broken boxes.
   visibility rather than display, so the layout does not jump when they
   arrive - the space is held, the glyph is not drawn. */
html body img:not([src]){ visibility:hidden; }
