/* Oriel — matter.css
   The physics of the room, as a kit: surfaces that read as real material (paper, lacquer, bone, metal) with weight, an
   edge, a shadow under them and one light over everything. Nothing here changes a screen on its own. A surface opts
   in with a class, so the look Kadian approved stays exactly as it is until a designer chooses where each piece lands.

     .slab        a surface with real thickness: a hairline catch of light on its lit edge, a micro bevel on the far one
     .levitate    a slab floating over the page: two linked shadows (a wide soft one that grounds it, a tight one cast
                  away from the light that stretches as it rises). Set its height with --z (px, default 8).
     .deboss      type pressed into the paper          .emboss  type standing up off it
     .callout     a detail set just outside its surface, tied to it by a 0.5px leader line (data-side="right|left|top")
     .detent      a switch that slides and locks like a ceramic block in a groove (aria-checked="true" when on)
     .chamfer     one stepped 45° corner (top right) with a registration mark: the signature. Wrap it in .chamfer-cast
                  to give it its shadow (a clipped surface can't cast its own).
     .ink-snap    a change that snaps into focus like e-ink pigment rearranging (Matter.snap(el) replays it)
     .ruler       the etched scroll ruler: Matter.ruler() puts one on the screen's edge
     .chamber     the sunken chamber behind everything: walls that shade and catch the light as it moves, and a pool
                  of light on its floor (one per page, behind the screens)
     .groove      the thinking channel: an engraved track whose marks run only while she produces (Matter.flow)
     .pigment     the press: a bloom of pigment rising through the pressed surface (matter.js places it)

   The light: matter.js moves --light-x and --light-y (-1 to 1) with the tilt of the phone (or the pointer on a
   computer). Rims and shadows follow it. Still when motion is reduced.

   Materials are tokens (--m-*). The room today has two: lacquer by night and bone by day. A new one (a paper, a stone,
   a metal) is one more block below, chosen with Matter.material(name). Fonts the same way (--f-*). See DESIGN.md. */

:root {
  /* the light at rest comes from the top left (Gemini, v66): shadows lean before the phone moves; matter.js adds the
     tilt to it. --light-deg points the sheen on surfaces away from the light */
  --light-x: -.35;
  --light-y: -.45;
  --light-deg: 142deg;
  /* motion: heavy, magnetic, never a bounce */
  --spring-heavy: cubic-bezier(.22, 1, .36, 1);
  --spring-settle: cubic-bezier(.16, 1, .3, 1);
  --t-snap: 90ms;
  --t-move: 560ms;
  /* type: the room's three voices; a new face is one more token */
  --f-display: var(--serif, "Cormorant Garamond", Georgia, serif);
  --f-text: var(--sans, "Outfit", system-ui, sans-serif);
  --f-mark: var(--mono, ui-monospace, "SF Mono", Menlo, monospace);
}

/* ---------------------------------------------------------------- materials */
:root, [data-material="lacquer"] {
  --m-rim-light: rgba(255, 236, 214, .17);
  --m-rim-shade: rgba(0, 0, 0, .55);
  --m-shadow: 0, 0, 0;
  --m-shadow-a: .62;
  --m-pigment: 212, 170, 108;      /* gold ink */
  --m-mark: rgba(255, 236, 214, .38);
  --m-groove: rgba(0, 0, 0, .42);
  --m-block: linear-gradient(180deg, #f6efe4, #d9cfc0);
  --m-floor: 222, 168, 104;        /* the light pool on the chamber floor: warm gold on the brown-black */
  --m-floor-a: .022;               /* by night a faint catch, never a haze: lacquer stays deep black */
  --m-wall: 0, 0, 0;               /* the chamber's walls in shade */
  --m-wall-a: .7;
  --m-wall-lit: 226, 178, 116;     /* a wall face catching the light, gold */
  --m-wall-lit-a: .045;
  /* Gemini's notes (v66 addendum): a warm copper, white-gold lettering, a cold ice-water accent */
  --m-copper: 184, 107, 67;        /* #B86B43 */
  --m-metal: 229, 215, 184;        /* #E5D7B8 */
  --m-ice: 168, 212, 236;          /* #A8D4EC */
  --m-ao-a: .62;                   /* the tight grounding shadow */
  --m-umbra-a: .78;                /* the cast that slides away from the light */
  --m-sheen: 236, 196, 140;        /* light lying across a surface, warm */
  --m-sheen-a: .035;
  --m-grain-a: .5;                 /* how strongly the paper's fibres catch the light */
  --m-glint: 212, 170, 108;        /* the bezel glint (Law 15): gold, running round a floating edge as the light moves */
  --m-surface: #1A1512; --m-surface-hi: #262019; --m-well: #080605;   /* its wafer, its lit top, its well (v69) */
  --m-water-lo: 143, 212, 245; --m-water-hi: 235, 250, 255;             /* the orb's water (v71): ice, its depth and its light */
  --m-trench-shade: rgba(0, 0, 0, .6);        /* the engraved divider (Law 18): a line of shade over a line of light */
  --m-trench-lit: rgba(255, 236, 214, .1);
}
html[data-theme="light"], [data-material="bone"] {
  --m-rim-light: rgba(255, 255, 255, .95);
  --m-rim-shade: rgba(70, 48, 26, .2);
  --m-shadow: 62, 42, 22;
  --m-shadow-a: .2;
  --m-pigment: 150, 104, 46;
  --m-mark: rgba(60, 40, 22, .42);
  --m-groove: rgba(60, 40, 22, .12);
  --m-block: linear-gradient(180deg, #ffffff, #ece5da);
  --m-floor: 255, 255, 255;
  --m-floor-a: .6;
  --m-wall: 70, 48, 26;
  --m-wall-a: .16;
  --m-wall-lit: 255, 255, 255;
  --m-wall-lit-a: .75;
  --m-copper: 143, 79, 50;         /* #8F4F32, oxidised bronze-copper */
  --m-metal: 74, 56, 40;           /* #4A3828, dark bronze lettering */
  --m-ice: 58, 124, 165;           /* #3A7CA5 */
  --m-ao-a: .10;
  --m-umbra-a: .18;
  --m-sheen: 255, 255, 255;
  --m-sheen-a: .5;
  --m-grain-a: 1;
  --m-glint: 196, 150, 86;
  --m-surface: #F4F0EA; --m-surface-hi: #FFFDF9; --m-well: #E6DFD4;
  --m-water-lo: 168, 209, 227; --m-water-hi: 247, 254, 255;
  --m-trench-shade: rgba(60, 40, 22, .14);
  --m-trench-lit: rgba(255, 255, 255, .9);
}
/* a new material goes here, e.g.
   [data-material="sakura"] { --m-rim-light: …; --m-shadow: …; --m-pigment: …; } */

/* ---------------------------------------------------------------- thickness and levitation */
.slab {
  box-shadow:
    inset calc(var(--light-x) * -1px) calc(1px + var(--light-y) * -.5px) 0 var(--m-rim-light),
    inset 0 -1px 0 var(--m-rim-shade);
}
.levitate {
  --z: 8;
  box-shadow:
    inset calc(var(--light-x) * -1px) calc(1px + var(--light-y) * -.5px) 0 var(--m-rim-light),
    inset 0 -1px 0 var(--m-rim-shade),
    0 calc(var(--z) * .35px) calc(var(--z) * 2.6px) calc(var(--z) * -.6px) rgba(var(--m-shadow), calc(var(--m-shadow-a) * .55)),
    calc(var(--light-x) * var(--z) * -.55px) calc((1.1 - var(--light-y) * .45) * var(--z) * 1px) calc(var(--z) * 1.15px) calc(var(--z) * -.45px) rgba(var(--m-shadow), var(--m-shadow-a));
  transition: box-shadow var(--t-move) var(--spring-heavy), transform var(--t-move) var(--spring-heavy);
}
.levitate.rise { --z: 16; transform: translateY(-2px); }

/* ---------------------------------------------------------------- the bezel glint (Law 15)
   A hairline of light (gold; silver on Slate) running round a floating surface's edge: its own layer, a conic sweep
   through a one-pixel ring cut by mask-composite, so the surface's own background is untouched. The hot spot sits on
   the edge facing the light and travels round as the phone tilts (--light-deg); a fainter catch lies opposite,
   where the far edge reflects the room. Still with reduced motion (the light doesn't move). */
.glint::before, .wcard::before, .tile::before, .sheet::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; padding: 1px; pointer-events: none;
  background: conic-gradient(from calc(var(--light-deg) + 158deg) at 50% 50%,
    rgba(var(--m-glint), 0) 0deg, rgba(var(--m-glint), .55) 14deg, rgba(var(--m-glint), .95) 22deg, rgba(var(--m-glint), .55) 30deg, rgba(var(--m-glint), 0) 50deg,
    rgba(var(--m-glint), 0) 176deg, rgba(var(--m-glint), .28) 202deg, rgba(var(--m-glint), 0) 228deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
}
.sheet { position: relative; isolation: isolate; }

/* ---------------------------------------------------------------- engraved dividers (Law 18)
   Between rows, a two-pixel trench instead of a flat hairline: a line of shade (the upper lip's shadow) over a line of
   light (the lower lip catching it), in each paper's own colours, so a group reads as blocks fitted together. */
.trench { box-shadow: 0 -1px 0 var(--m-trench-lit), 0 -2px 0 var(--m-trench-shade); }

/* ---------------------------------------------------------------- pressed type */
.deboss { text-shadow: 0 -1px 0 var(--m-rim-shade), 0 1px 0 var(--m-rim-light); }
.emboss { text-shadow: 0 1px 0 var(--m-rim-shade), 0 -1px 0 var(--m-rim-light), calc(var(--light-x) * -1px) 2px 3px rgba(var(--m-shadow), calc(var(--m-shadow-a) * .6)); }

/* ---------------------------------------------------------------- margin callouts */
.callout-host { position: relative; overflow: visible; }
.callout {
  position: absolute; top: 14px; left: calc(100% + 14px); white-space: nowrap;
  font-family: var(--f-mark); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--m-mark);
}
.callout::before { content: ""; position: absolute; top: 50%; right: calc(100% + 3px); width: 11px; height: .5px; background: var(--m-mark); }
.callout[data-side="left"] { left: auto; right: calc(100% + 14px); }
.callout[data-side="left"]::before { right: auto; left: calc(100% + 3px); }
.callout[data-side="top"] { top: auto; bottom: calc(100% + 10px); left: 16px; }
.callout[data-side="top"]::before { top: calc(100% + 2px); right: auto; left: 0; width: .5px; height: 8px; }

/* ---------------------------------------------------------------- the detent switch */
.detent {
  position: relative; display: inline-block; flex: none; width: 46px; height: 26px; border-radius: 7px;
  background: var(--m-groove); box-shadow: inset 0 1px 2px rgba(var(--m-shadow), .5), inset 0 -1px 0 var(--m-rim-light);
}
.detent::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 5px; background: var(--m-block);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 2px 3px rgba(var(--m-shadow), .45), calc(var(--light-x) * -1px) 3px 6px rgba(var(--m-shadow), .3);
  transition: transform var(--t-move) var(--spring-heavy);
}
.detent[aria-checked="true"]::after, [aria-checked="true"] > .detent::after { transform: translateX(20px); }
.detent[aria-checked="true"], [aria-checked="true"] > .detent { background: rgba(var(--m-pigment), .3); }

/* ---------------------------------------------------------------- the signature corner */
.chamfer { --cut: 18px; clip-path: polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%); }
.chamfer-cast { filter: drop-shadow(0 calc(var(--z, 8) * 1px) calc(var(--z, 8) * 1.1px) rgba(var(--m-shadow), var(--m-shadow-a))); }
.chamfer-mark { position: absolute; top: 4px; right: 4px; width: 9px; height: 9px; pointer-events: none; opacity: .7;
  background: linear-gradient(var(--m-mark), var(--m-mark)) center / 9px .5px no-repeat, linear-gradient(var(--m-mark), var(--m-mark)) center / .5px 9px no-repeat; }

/* ---------------------------------------------------------------- ink snap */
.ink-snap { animation: ink-snap calc(var(--t-snap) * 3) steps(3, end) both; }
@keyframes ink-snap {
  0% { opacity: .25; filter: contrast(2.2) brightness(.55); }
  34% { opacity: 1; filter: contrast(1.6) brightness(1.18); }
  100% { opacity: 1; filter: none; }
}

/* ---------------------------------------------------------------- the scroll ruler */
.ruler {
  position: fixed; top: 22vh; bottom: 22vh; right: 3px; width: 7px; z-index: 30; pointer-events: none; opacity: 0;
  transition: opacity .8s var(--spring-heavy);
  -webkit-mask: linear-gradient(transparent, #000 18%, #000 82%, transparent); mask: linear-gradient(transparent, #000 18%, #000 82%, transparent);
  background:
    repeating-linear-gradient(180deg, var(--m-mark) 0 .5px, transparent .5px var(--tick, 6px)) right top / 4px 100% no-repeat,
    repeating-linear-gradient(180deg, var(--m-mark) 0 .5px, transparent .5px calc(var(--tick, 6px) * 5)) right top / 7px 100% no-repeat;
  background-position-y: var(--ruler-y, 0px), var(--ruler-y, 0px);
}
.ruler.on { opacity: .8; }


/* ---------------------------------------------------------------- the sunken chamber
   The screen is a recess, not a page: four walls around the room, the one the light is on in shade, the one facing it
   catching light, and a pool of light on the floor that slides as the device tilts. Only opacity and position move
   (compositor work, never a repaint), and the walls are drawn once. Markup: <div class="chamber"><i class="floor"></i>
   <i class="w t"></i><i class="w r"></i><i class="w b"></i><i class="w l"></i></div>, placed after the room's own
   layers (stars, bamboo) and before the screens. Depth of the walls: --wall (px). */
.chamber { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; --wall: 30px; }
.chamber i { position: absolute; display: block; }
.chamber .floor {
  left: -40%; top: -40%; width: 180%; height: 180%; will-change: translate;
  background: radial-gradient(closest-side, rgba(var(--m-floor), var(--m-floor-a)), rgba(var(--m-floor), calc(var(--m-floor-a) * .35)) 48%, rgba(var(--m-floor), 0));
  -webkit-mask: radial-gradient(closest-side, #000 30%, transparent); mask: radial-gradient(closest-side, #000 30%, transparent);
  translate: calc(var(--light-x) * 23vw) calc(var(--light-y) * 20vh);
}
/* the light catching the paper's grain: fibres drawn once (matter.js, "lit-grain") lie still in the paper while the
   pool of light slides over them, so they catch it and let it go as the wrist turns. The pool moves; the fibres move
   back by the same amount, so they stay put. Position only, never a repaint. Markup: <i class="floor"><b></b></i> */
.chamber .floor b {
  position: absolute; inset: -14%; display: block; will-change: translate; opacity: var(--m-grain-a, .7);
  background-image: var(--tex-lit-grain, none); background-size: var(--tex-lit-grain-size, 256px) var(--tex-lit-grain-size, 256px);
  translate: calc(var(--light-x) * -23vw) calc(var(--light-y) * -20vh);
}
/* each wall: its shade (where the light can't reach) and its lit face (where it can), crossfading as the light moves */
.chamber .w { will-change: opacity; }
.chamber .w::before, .chamber .w::after { content: ""; position: absolute; inset: 0; }
.chamber .t { left: 0; right: 0; top: 0; height: var(--wall); }
.chamber .b { left: 0; right: 0; bottom: 0; height: var(--wall); }
.chamber .l { top: 0; bottom: 0; left: 0; width: var(--wall); }
.chamber .r { top: 0; bottom: 0; right: 0; width: var(--wall); }
.chamber .t::before { background: linear-gradient(180deg, rgba(var(--m-wall), var(--m-wall-a)), rgba(var(--m-wall), 0)); opacity: clamp(0, calc(.75 - var(--light-y) * .55), 1); }
.chamber .b::before { background: linear-gradient(0deg, rgba(var(--m-wall), var(--m-wall-a)), rgba(var(--m-wall), 0)); opacity: clamp(0, calc(.3 + var(--light-y) * .6), 1); }
.chamber .l::before { background: linear-gradient(90deg, rgba(var(--m-wall), var(--m-wall-a)), rgba(var(--m-wall), 0)); opacity: clamp(0, calc(.45 - var(--light-x) * .6), 1); }
.chamber .r::before { background: linear-gradient(270deg, rgba(var(--m-wall), var(--m-wall-a)), rgba(var(--m-wall), 0)); opacity: clamp(0, calc(.45 + var(--light-x) * .6), 1); }
.chamber .t::after { height: 40%; background: linear-gradient(180deg, rgba(var(--m-wall-lit), var(--m-wall-lit-a)), rgba(var(--m-wall-lit), 0)); opacity: clamp(0, calc(var(--light-y) * .9), 1); }
.chamber .b::after { top: auto; height: 40%; background: linear-gradient(0deg, rgba(var(--m-wall-lit), var(--m-wall-lit-a)), rgba(var(--m-wall-lit), 0)); opacity: clamp(0, calc(.45 - var(--light-y) * .7), 1); }
.chamber .l::after { width: 40%; background: linear-gradient(90deg, rgba(var(--m-wall-lit), var(--m-wall-lit-a)), rgba(var(--m-wall-lit), 0)); opacity: clamp(0, calc(.25 + var(--light-x) * .8), 1); }
.chamber .r::after { left: auto; width: 40%; background: linear-gradient(270deg, rgba(var(--m-wall-lit), var(--m-wall-lit-a)), rgba(var(--m-wall-lit), 0)); opacity: clamp(0, calc(.25 - var(--light-x) * .8), 1); }
@media (min-width: 720px) { .chamber { --wall: 46px; } }

/* ---------------------------------------------------------------- floating surfaces, as tokens
   A surface sets its height (--z, px) and builds its box-shadow from these, so its own hairlines stay and the lift
   follows the one light: --lev-rim (the lit edge), --lev-base (the bevel underneath), --lev-ground (a tight ambient
   shadow that grounds its mass) and --lev-cast (the umbra, sliding opposite the light, longer and softer the higher
   it rides). The shadow math is Gemini's (v66 addendum).
   A surface opts in with class="lift"; the room's own floating surfaces are listed here too. */
.lift, .levitate, .wcard, .tile, .sheet, .group, .card, .folio, .silk, .gcard {
  --z: 8;
  --lev-rim: inset calc(var(--light-x) * -1.5px) calc(1px + var(--light-y) * -.75px) 0 var(--m-rim-light);
  --lev-base: inset 0 -1px 0 var(--m-rim-shade);
  --lev-ground: 0 calc(var(--z) * .35px) calc(var(--z) * .8px) -2px rgba(var(--m-shadow), var(--m-ao-a));
  --lev-cast: calc(var(--light-x) * var(--z) * -.95px) calc((var(--light-y) * -.95 + .65) * var(--z) * 1px) calc(var(--z) * 1.85px) -3px rgba(var(--m-shadow), var(--m-umbra-a));
}
/* a near surface also slides a little against the room behind it: depth you can see when the phone moves */
.near { translate: calc(var(--light-x) * var(--z, 8) * -.16px) calc(var(--light-y) * var(--z, 8) * -.16px); }

/* ---------------------------------------------------------------- the thinking channel
   An engraved track beside the thinking pearl: fine ticks, tall ticks and a gold mark, each on its own rhythm, so the
   tape never reads as a pattern. It runs only when she produces something (Matter.flow), and stands still while she
   waits: the motion is real. The line beside it says what she's doing. */
.groove {
  position: relative; display: block; width: 96px; height: 6px; border-radius: 3px; overflow: hidden;
  background-color: var(--m-groove);
  background-image:
    linear-gradient(90deg, rgba(var(--m-pigment), .95) 0 1.5px, transparent 1.5px),
    linear-gradient(90deg, var(--m-mark) 0 1px, transparent 1px),
    linear-gradient(90deg, var(--m-mark) 0 .75px, transparent .75px);
  background-size: 41px 100%, 13px 64%, 5px 34%;
  background-repeat: repeat-x;
  background-position: calc(var(--run, 0) * -1.3px) 50%, calc(var(--run, 0) * -1px) 50%, calc(var(--run, 0) * -.62px) 50%;
  box-shadow: inset 0 1px 1.5px rgba(var(--m-shadow), .55), inset 0 -.5px 0 var(--m-rim-light);
  -webkit-mask: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent); mask: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent);
  transition: background-position .5s linear;
}

/* ---------------------------------------------------------------- the press
   Pigment rising through the pressed surface from under the finger (phones have no hover; this is their answer). */
.pigment { position: fixed; z-index: 40; pointer-events: none; overflow: hidden; }
.pigment b {
  position: absolute; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%; scale: .4; opacity: 1;
  background: radial-gradient(closest-side, rgba(var(--m-pigment), .26), rgba(var(--m-pigment), .12) 52%, rgba(var(--m-pigment), 0));
  transition: scale .62s var(--spring-heavy), opacity .55s ease;
}
.pigment b.up { scale: var(--reach, 8); }
.pigment b.out { opacity: 0; transition: scale .62s var(--spring-heavy), opacity .5s ease .06s; }
html[data-theme="light"] .pigment b { background: radial-gradient(closest-side, rgba(var(--m-pigment), .2), rgba(var(--m-pigment), .09) 52%, rgba(var(--m-pigment), 0)); }

@media (prefers-reduced-motion: reduce) {
  .levitate, .detent::after, .ruler, .groove { transition: none; }
  .ink-snap { animation: none; }
  .near, .chamber .floor, .chamber .floor b { translate: none; }
}
