/* STACKABLES materials: every control is a small part made of the same wood, stone, clay and ceramic as the towers.
   A part has a face (the texture, lit from the top left) and a side under it; pressing it pushes the face down over the side.
   Shared by the site pages and the constructor. The textures in tex/ are the collection's own tiles (see make_tex.py).

   .press       the mechanics: face, side, shadow, press and release; pick a material with one more class
   .blk         a button made as a slab              .blk.sm  a smaller one        .blk.round  a disc (icon buttons)
   .slab        a part that does not press (cards, sheets)
   .carve       a field cut into stone               .groove  a progress track with clay in it
   materials    .walnut .pine .oak .clay .ivory .turquoise .granite .basalt (.ivory is the default)
   states       :active and .is-down press it; aria-pressed="true" and aria-current="page" keep it down; [disabled] sinks it */

/* the two type faces, here so the constructor gets them too (they sit next to this file in fonts/) */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap; src: url('fonts/inter-latin.woff2') format('woff2'); }
@font-face { font-family: 'Unbounded'; font-style: normal; font-weight: 200 900; font-display: swap; src: url('fonts/unbounded-latin.woff2') format('woff2'); }

/* a material is a few custom properties; ivory is the default (zero specificity, so any material class wins) */
:where(.press, .slab), .ivory { --tex: url('tex/ivory.webp'); --ts: 256px; --base: #ede3cc; --side: #c9b993; --fg: #2a2119; --fg-sh: 0 1px 0 rgba(255, 255, 255, .8); --lit: .5; --gloss: 1; }
.walnut    { --tex: url('tex/walnut.webp');     --ts: 384px; --base: #67492f; --side: #3a2817; --fg: #f7ecd8; --fg-sh: 0 -1px 0 rgba(20, 10, 2, .55); --lit: .14; --gloss: 0; }
.pine      { --tex: url('tex/pine.webp');       --ts: 384px; --base: #d1b88e; --side: #9c7c50; --fg: #36261a; --fg-sh: 0 1px 0 rgba(255, 246, 226, .6); --lit: .22; --gloss: 0; }
.oak       { --tex: url('tex/oak.webp');        --ts: 384px; --base: #ab8354; --side: #6e4f2c; --fg: #24170c; --fg-sh: 0 1px 0 rgba(255, 228, 190, .4); --lit: .18; --gloss: 0; }
.clay      { --tex: url('tex/terracotta.webp'); --ts: 256px; --base: #b86440; --side: #7f3a1f; --fg: #fff4e8; --fg-sh: 0 -1px 0 rgba(70, 20, 0, .45); --lit: .16; --gloss: 0; }
.turquoise { --tex: url('tex/turquoise.webp');  --ts: 256px; --base: #509a94; --side: #2c615c; --fg: #f4fbf9; --fg-sh: 0 -1px 0 rgba(0, 40, 36, .45); --lit: .3; --gloss: 1; }
.granite   { --tex: url('tex/granite.webp');    --ts: 256px; --base: #8b8985; --side: #55534f; --fg: #1d1915; --fg-sh: 0 1px 0 rgba(255, 255, 255, .3); --lit: .2; --gloss: 0; }
.limestone { --tex: url('tex/limestone.webp');  --ts: 256px; --base: #d9d0b4; --side: #a99d7c; --fg: #2a2119; --fg-sh: 0 1px 0 rgba(255, 255, 255, .6); --lit: .3; --gloss: 0; }
.basalt    { --tex: url('tex/basalt.webp');     --ts: 256px; --base: #39393b; --side: #1c1c1e; --fg: #efe9dd; --fg-sh: 0 -1px 0 rgba(0, 0, 0, .6); --lit: .1; --gloss: 0; }

/* ---- the mechanics ---------------------------------------------------------------------------------------------- */
.press, .slab {
  --d: 5px;                      /* how thick the part is: the side shows this much under the face */
  --r: 14px;
  position: relative; isolation: isolate; border: 0; background: none; color: var(--fg);
  border-radius: var(--r); transform: translateY(0); -webkit-tap-highlight-color: transparent;
}
.press { text-shadow: var(--fg-sh); }
.press { cursor: pointer; transition: transform .2s cubic-bezier(.25, 1.7, .45, 1); -webkit-user-select: none; user-select: none; touch-action: manipulation; }
/* the side: the same material in shade, set under the face, with the shadow it casts on the page */
.press::before, .slab::before {
  content: ''; position: absolute; inset: 0; z-index: -2; border-radius: inherit; pointer-events: none;
  background: var(--tex) 0 0 / var(--ts) var(--side); background-blend-mode: multiply;
  transform: translateY(var(--d));
  box-shadow: 0 1px 1px rgba(40, 26, 12, .28), 0 3px 5px -1px rgba(40, 26, 12, .26), 0 12px 22px -10px rgba(40, 26, 12, .5);
  transition: transform .2s cubic-bezier(.25, 1.7, .45, 1), box-shadow .2s ease-out;
}
/* the face: the texture, light from above, a rounded edge, and on glazed ceramic a soft shine */
.press::after, .slab::after {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background:
    radial-gradient(130% 120% at 28% -10%, rgba(255, 255, 255, calc(var(--gloss, 0) * .55)), rgba(255, 255, 255, 0) 46%),
    linear-gradient(180deg, rgba(255, 250, 240, var(--lit)) 0%, rgba(255, 250, 240, 0) 42%, rgba(30, 18, 6, .1) 100%),
    var(--tex) 0 0 / var(--ts) var(--base);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, calc(.25 + var(--gloss, 0) * .4)),
    inset 0 -2px 1px -1px rgba(20, 10, 0, .22),
    inset 0 0 0 1px rgba(30, 18, 6, .1);
  transition: filter .2s ease-out;
}
@media (hover: hover) {
  .press:hover { transform: translateY(-1px); }
  .press:hover::before { transform: translateY(calc(var(--d) + 1px)); }
  .press:hover::after { filter: brightness(1.05) saturate(1.04); }
}
/* pressed: the face goes down until only a sliver of the side is left */
.press:active, .press.is-down, .press[aria-pressed="true"], .press[aria-current="page"] { transform: translateY(calc(var(--d) - 1px)); transition-duration: .05s; transition-timing-function: ease-out; }
.press:active::before, .press.is-down::before, .press[aria-pressed="true"]::before, .press[aria-current="page"]::before {
  transform: translateY(1px); transition-duration: .05s;
  box-shadow: 0 1px 1px rgba(40, 26, 12, .3), 0 2px 3px -1px rgba(40, 26, 12, .22);
}
.press:active::after, .press.is-down::after { filter: brightness(.96); }
/* a switch that stays on: down, and a little darker, as if it sat lower in the light */
.press[aria-pressed="true"]::after, .press[aria-current="page"]::after {
  filter: brightness(.93) saturate(1.05);
  box-shadow: inset 0 2px 4px rgba(20, 10, 0, .28), inset 0 0 0 1px rgba(30, 18, 6, .14);
}
.press[disabled], .press[aria-disabled="true"] { cursor: default; pointer-events: none; opacity: .55; transform: translateY(calc(var(--d) - 2px)); filter: saturate(.6); }
.press[disabled]::before, .press[aria-disabled="true"]::before { transform: translateY(2px); box-shadow: none; }
.press:focus-visible { outline: 2px solid #2a2119; outline-offset: 4px; }

/* ---- shapes ----------------------------------------------------------------------------------------------------- */
.blk {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; padding: 0 22px;
  margin-bottom: var(--d); font: inherit; font-weight: 650; font-size: 16px; line-height: 1.1; letter-spacing: -.005em;
  text-decoration: none; white-space: nowrap;
}
.blk.sm { --d: 4px; --r: 12px; min-height: 40px; padding: 0 15px; font-size: 15px; font-weight: 600; }
.blk.round { --d: 4px; --r: 50%; width: 44px; height: 44px; min-height: 0; padding: 0; }
.blk.round.sm { width: 40px; height: 40px; }
.blk.round svg { width: 20px; height: 20px; }
.blk svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(var(--fg-sh)); flex: none; }
.slab { --d: 7px; --r: var(--radius, 26px); margin-bottom: var(--d); }
.slab::before { box-shadow: 0 2px 2px rgba(40, 26, 12, .18), 0 26px 50px -24px rgba(40, 26, 12, .55); }

/* a field cut into stone: the light falls on its lower edge, the shadow on its upper one */
.carve {
  min-height: 48px; padding: 0 14px; border: 0; border-radius: 12px; color: #2a2119; font: inherit; font-size: 16px;
  background: linear-gradient(180deg, rgba(40, 26, 12, .12), rgba(255, 255, 255, 0) 40%), url('tex/limestone.webp') 0 0 / 256px #d9d0b4;
  box-shadow: inset 0 2px 3px rgba(40, 26, 12, .32), inset 0 1px 1px rgba(40, 26, 12, .25), inset 0 -1px 0 rgba(255, 255, 255, .55), 0 1px 0 rgba(255, 255, 255, .7);
}
.carve::placeholder { color: rgba(42, 33, 25, .5); }
.carve:focus-visible { outline: 2px solid #2a2119; outline-offset: 3px; }

/* progress: a groove in stone, filled with clay */
.groove {
  height: 10px; border-radius: 99px; overflow: hidden;
  background: url('tex/limestone.webp') 0 0 / 256px #d9d0b4;
  box-shadow: inset 0 2px 3px rgba(40, 26, 12, .35), inset 0 -1px 0 rgba(255, 255, 255, .5), 0 1px 0 rgba(255, 255, 255, .7);
}
.groove > i {
  display: block; height: 100%; border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 240, 220, .35), rgba(255, 240, 220, 0) 50%, rgba(60, 20, 0, .2)), url('tex/terracotta.webp') 0 0 / 256px #b86440;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 1px 0 1px rgba(40, 26, 12, .25);
}

@media (prefers-reduced-motion: reduce) { .press, .press::before, .press::after { transition: none; } }
