/* Liquid glass calculator · stage 7 — the scientific morph. The layout in use is .stage[data-layout]: basic 4 × 5,
   sci-wide 10 × 5, sci-tall 6 × 10. The scientific keys get their own label size, superscripts and the faces under
   2nd and Rad/Deg; the display gets its memory and Rad flags.

   Every size comes from one number, --key (a key's side), which app.js works out from the screen's width AND height
   for the layout in use. The proportions it uses (--gap-r, --pad-r, --display-r) are set by app.js too, so the sum it
   solves and the boxes drawn here always agree.

   1 tokens: primitive → semantic → component     2 the page             3 the calculator: display, bar, keys, labels
   4 the history tape's place                       5 the hint and toast   7 screens      8 when there is no WebGL
   9 reduced motion */

/* ---- 1. TOKENS ---- */
/* primitive: the raw values, named for what they are */
:root {
  --studio-50: #F6F6F8; --studio-100: #ECEDF1; --studio-200: #DFE0E6; --studio-500: #8B8E99; --studio-900: #22242C;
  --ink-900: #1D1E23; --ink-800: #23242A;
  --violet-500: #6B47FF;
  --white: #FFFFFF;

  --font-display: 'Inter Tight', 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-body: 'Inter', ui-sans-serif, system-ui, sans-serif;

  --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px;
  --radius-pill: 999px;
}

/* semantic: what each value is for on this page */
:root {
  --page: var(--studio-100);
  --on-page: var(--studio-900);
  --on-page-muted: var(--studio-500);
  --focus: var(--violet-500);
  --gutter: max(var(--space-4), env(safe-area-inset-left), env(safe-area-inset-right));
}

/* component: the calculator's sizes. --key and the ratios are written by app.js (fit) on .stage, so a new size
   restyles the calculator only, not the whole page; these are first-paint defaults */
.stage {
  --key: 72px; --gap-r: .175; --pad-r: .27; --display-r: 2.3; --cols: 4; --rows: 5;
  --key-gap: calc(var(--key) * var(--gap-r));
  --calc-pad: calc(var(--key) * var(--pad-r));
  --calc-radius: calc(var(--key) * .64);
  --display-h: calc(var(--key) * var(--display-r));
  --num-size: calc(var(--key) * 1.02);
  --expr-size: max(13px, calc(var(--key) * .22));
  --tool-size: max(36px, calc(var(--key) * .5));
  --key-label-size: calc(var(--key) * .42);
  --key-fn-size: calc(var(--key) * .33);
  --key-op-size: calc(var(--key) * .5);
  --key-sci-size: max(12px, calc(var(--key) * .27));
}
/* component: the calculator's inks (the tone below sets them for its studio) */
:root {
  --display-ink: var(--white);
  --display-shade: 0 1px 2px rgb(30 30 60 / .45), 0 4px 22px rgb(30 30 60 / .38);
  --expr-ink: rgb(255 255 255 / .85);
  --label-ink: var(--white);
  --label-shade: 0 1px 1px rgb(20 10 60 / .35), 0 2px 12px rgb(20 10 60 / .35);
  --tool-press: rgb(255 255 255 / .16);
}
/* the scientific layouts: a shorter number, so the wide display keeps its proportions */
.stage[data-layout="sci-wide"], .stage[data-layout="sci-tall"] { --num-size: calc(var(--key) * .86); }
/* a finger needs 44 px: the tool bar's buttons never get smaller than that on a touch screen */
@media (pointer: coarse) { .stage { --tool-size: max(44px, calc(var(--key) * .5)); } }

/* the tone (app.js sets html[data-tone]; stage 9 adds four more) */
:root[data-tone="classic"] {
  --display-ink: var(--ink-900); --display-shade: 0 1px 0 rgb(255 255 255 / .5); --expr-ink: var(--display-ink);
  --label-ink: var(--ink-800); --label-shade: 0 1px 0 rgb(255 255 255 / .55); --tool-press: rgb(29 30 35 / .07);
}

/* ---- 2. the page: a studio, nothing else ---- */
* { box-sizing: border-box; }
html { background: var(--page); -webkit-text-size-adjust: 100%; }
body { margin: 0; font-family: var(--font-body); color: var(--on-page); background: var(--page); -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent; overflow-x: hidden; }
button { font: inherit; color: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

.page { position: relative; min-height: 100svh; isolation: isolate; overflow: hidden; display: grid; place-items: center; }
.gl, .fallback-bg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; display: block; }
.fallback-bg { display: none; }
.stage { display: flex; flex-direction: column; align-items: center; gap: var(--space-5); max-width: 100%;
  padding: max(var(--space-4), env(safe-area-inset-top)) var(--gutter) max(var(--space-4), env(safe-area-inset-bottom)); }

/* ---- 3. the calculator ---- */
.calc-home { position: relative; display: flex; align-items: flex-start; }
/* the slab: transparent here — the canvas draws the glass exactly under it, moved by the same transform */
.calc { position: relative; flex: none; width: calc(var(--cols) * var(--key) + (var(--cols) - 1) * var(--key-gap) + 2 * var(--calc-pad));
  padding: 0 var(--calc-pad) var(--calc-pad); border-radius: var(--calc-radius);
  touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none; transform-origin: 50% 50%; }
.calc.is-dragging { cursor: grabbing; }

/* the display: the tool bar on top, then the sum as typed, then the number (the live result) */
.display { position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-end; height: var(--display-h);
  padding: 0 calc(var(--key) * .1) calc(var(--key) * .14); }
.bar { position: absolute; top: calc(var(--calc-pad) * .55); left: calc(var(--calc-pad) * -.25); right: calc(var(--key) * .08);
  display: flex; align-items: center; justify-content: space-between; pointer-events: none; }
.tools { display: flex; gap: calc(var(--key) * .04); pointer-events: auto; }
.tool { display: grid; place-items: center; width: var(--tool-size); height: var(--tool-size); padding: 0; border: 0; border-radius: 50%;
  color: var(--display-ink); background: transparent; opacity: .72; cursor: pointer; transition: opacity .15s, background-color .15s; }
.tool:hover { opacity: 1; background: var(--tool-press); }
.tool[aria-pressed="true"], .tool[aria-expanded="true"] { opacity: 1; background: var(--tool-press); }
.tool svg { width: 56%; height: 56%; }
.flags { display: flex; gap: var(--space-2); margin: 0; font: 600 max(11px, calc(var(--key) * .16))/1 var(--font-body); letter-spacing: .06em;
  text-transform: uppercase; color: var(--display-ink); opacity: .6; }
.flag[hidden] { display: none; }

/* the sum as typed: two lines at most; longer, it becomes one line that scrolls to keep its end in view, fading out
   on the left (app.js sets .is-long and the scroll) */
.expr { max-width: 100%; max-height: calc(var(--expr-size) * 1.25 * 2); margin: 0; overflow: hidden; text-align: right;
  font: 400 var(--expr-size)/1.25 var(--font-display); color: var(--expr-ink); opacity: .7; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; text-shadow: 0 1px 6px rgb(40 30 90 / .25); overflow-wrap: anywhere; }
.expr.is-long { white-space: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 2.5em); mask-image: linear-gradient(90deg, transparent, #000 2.5em); }
.expr.is-long::-webkit-scrollbar { display: none; }
.expr.is-error { opacity: .9; }
.readout { display: flex; justify-content: flex-end; width: 100%; }
.num { display: block; max-width: 100%; min-width: 44px; min-height: 44px; padding: 0; text-align: right; border: 0; background: none; cursor: copy; touch-action: pan-y;
  font: 200 var(--num-size)/1.02 var(--font-display); letter-spacing: -.035em; white-space: nowrap; font-variant-numeric: tabular-nums;
  color: var(--display-ink); text-shadow: var(--display-shade); }
.num:focus { outline: none; }
.num:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 8px; }

.keys { display: grid; grid-template-columns: repeat(var(--cols), var(--key)); grid-template-rows: repeat(var(--rows), var(--key)); gap: var(--key-gap); }
.key { position: relative; display: grid; place-items: center; width: var(--key); height: var(--key); padding: 0; border: 0; border-radius: var(--radius-pill);
  background: none; color: var(--label-ink); cursor: pointer; touch-action: manipulation; -webkit-user-select: none; user-select: none; will-change: transform; }
.key[hidden] { display: none; }
.key.zero { width: auto; justify-items: start; padding-left: calc(var(--key) / 2 - .3em); }
.lbl { display: block; font: 300 var(--key-label-size)/1 var(--font-display); letter-spacing: -.02em; pointer-events: none; text-shadow: var(--label-shade); white-space: nowrap; }
.key.fn .lbl { font-size: var(--key-fn-size); font-weight: 400; }
.key.op .lbl { font-size: var(--key-op-size); font-weight: 300; margin-top: -2px; }
.key.sci .lbl { font-size: var(--key-sci-size); font-weight: 400; letter-spacing: 0; }
.lbl sup, .lbl sub { font-size: .66em; line-height: 0; }
/* a key with two faces (AC/⌫, the functions under 2nd, Rad/Deg): both are laid out in the same cell, one attribute on
   the keypad shows one of them (keypad.js) — switching repaints a few keys and lays out nothing */
.key > .lbl { grid-area: 1 / 1; }
.lbl-b { opacity: 0; }
.keys[data-typing="true"] [data-face="typing"] .lbl-a, .keys[data-second="true"] [data-face="second"] .lbl-a,
.keys[data-angle="true"] [data-face="angle"] .lbl-a { opacity: 0; }
.keys[data-typing="true"] [data-face="typing"] .lbl-b, .keys[data-second="true"] [data-face="second"] .lbl-b,
.keys[data-angle="true"] [data-face="angle"] .lbl-b { opacity: 1; }
.key.op[aria-pressed="true"] .lbl, .key.sci[aria-pressed="true"] .lbl { font-weight: 600; }
.key:focus { outline: none; }
.key:focus-visible { outline: 2.5px solid var(--white); outline-offset: 3px; box-shadow: 0 0 0 6px rgb(107 71 255 / .55); }

/* ---- 4. the history tape: docked beside the glass on wide screens (a sheet on phones: history.css § 5) ----
   Docked, it takes no room in the layout: app.js (placeTape) works out, once per layout, where it goes beside the
   glass — the glass itself moves aside and shrinks as a transform when the tape opens — so opening it lays out nothing */
.tape { position: absolute; top: 0; left: 0; width: 0; height: 0; }
@media (min-width: 720px) and (min-height: 501px), (min-width: 720px) and (orientation: portrait) {
  /* a blur on a moving canvas would be redone every frame: the studio behind it is smooth, so a little more opaque
     glass looks the same without it */
  .tape .ch-panel { position: fixed; top: var(--tape-y, 0); left: var(--tape-x, 0); width: var(--tape-w, 320px); max-height: var(--ch-dock-h, 70vh);
    -webkit-backdrop-filter: none; backdrop-filter: none; --ch-glass: rgb(255 255 255 / .62); --ch-glass-deep: rgb(255 255 255 / .4); }
}

/* on a phone the tape is a sheet over the glass: a blur there would be redone every frame the liquid moves under it,
   so the sheet is near-opaque glass instead (the scrim already quiets what is behind) */
@media (max-width: 719px), (max-height: 500px) and (orientation: landscape) {
  .tape .ch-panel { -webkit-backdrop-filter: none; backdrop-filter: none; --ch-glass: rgb(250 250 252 / .94); --ch-glass-deep: rgb(244 245 248 / .9); }
}

/* ---- 5. the hint and the toast ---- */
.hint { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-3); margin: 0; font: 500 13px var(--font-body); color: var(--on-page-muted);
  letter-spacing: .01em; text-align: center; max-width: 100%; }
.hint-touch { display: none; }
@media (hover: none) and (pointer: coarse) { .hint-pointer { display: none; } .hint-touch { display: inline; } }

.toast { position: fixed; left: 50%; bottom: max(var(--space-5), env(safe-area-inset-bottom)); z-index: 70; padding: 10px 18px; border-radius: var(--radius-pill);
  font: 600 13.5px/1.2 var(--font-body); color: var(--ink-900); background: rgb(255 255 255 / .74);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .8), 0 14px 30px -14px rgb(30 30 60 / .4);
  -webkit-backdrop-filter: blur(18px) saturate(1.5); backdrop-filter: blur(18px) saturate(1.5);
  opacity: 0; visibility: hidden; transform: translate(-50%, 10px); pointer-events: none;
  transition: opacity .18s, transform .25s cubic-bezier(.2, .8, .2, 1), visibility 0s linear .25s; }
.toast.is-on { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition: opacity .18s, transform .25s cubic-bezier(.2, .8, .2, 1), visibility 0s; }

/* ---- 7. screens: the sizes come from --key (app.js); a short landscape screen has no room for the hint ---- */
@media (max-height: 500px) and (orientation: landscape) {
  .stage { gap: 0; padding-top: max(var(--space-2), env(safe-area-inset-top)); padding-bottom: max(var(--space-2), env(safe-area-inset-bottom)); }
  .hint { display: none; }
}

/* ---- 8. when there is no WebGL 2: a frosted slab and frosted keys over a still studio ---- */
.no-gl .gl { display: none; }
.no-gl .fallback-bg { display: block; background: radial-gradient(60% 50% at 50% 40%, var(--studio-50), var(--studio-100) 70%, var(--studio-200)); }
.no-gl .calc { background: linear-gradient(180deg, rgb(255 255 255 / .45), rgb(255 255 255 / .2));
  box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / .8), 0 40px 80px -30px rgb(40 40 60 / .4); overflow: hidden; }
.no-gl .key { background: radial-gradient(120% 120% at 30% 20%, rgb(255 255 255 / .45), rgb(255 255 255 / .1) 60%); box-shadow: inset 0 1px 0 rgb(255 255 255 / .7), inset 0 0 0 1px rgb(255 255 255 / .35); }
.no-gl .liquid2d { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: inherit; pointer-events: none; }

/* ---- 9. reduced motion (app.js: no slosh, bubbles, squash or morph) ---- */
@media (prefers-reduced-motion: reduce) {
  .calc { cursor: default; }
  .toast, .tool { transition: none; }
}
