/* The light layer: fork C, "one light", ported from mocks/tiles-glass/c on the
 * tiles-glass branch (8415d32). Added next to tiles.css, cards.css and hero.css
 * and never carved into them: this file restyles the plate, the tile, the
 * card and the hero panel from outside, through the tokens in
 * light.tokens.css and the properties site/light.js writes. Remove the two
 * links and the script and the site is exactly what it was.
 *
 * Every object on the page is lit from the same point. At rest that point is
 * the sun in the photograph; while the pointer is inside the sheet, the pointer
 * is the lamp. Nothing here knows which: each plate is handed the light's
 * position (--lx/--ly from the sheet, or the sun from the tokens) and its own
 * centre (--ox/--oy), and works out where its highlight and its cast shadow
 * fall. Eighteen objects therefore answer one point, as objects on one desk do,
 * instead of eighteen private hovers.
 *
 * The plates are graphite. A near-white plate on a near-white sheet gives a
 * light nothing to do; a dark body is what makes a moving highlight legible,
 * and the moving highlight is the whole layer. */

/* --- the hover law ----------------------------------------------------- */
/* base.css transitions box-shadow on the plate and background on the pill;
   the tile transitions its hairline. A pointer may only move, fade or filter
   a thing here, so those declarations are retired once and every hover below
   is built from a layer that fades or moves rather than a box that repaints. */
.tile, .plate, .pill, .card-link .icon, .site-nav a {
  transition-property: transform, opacity, filter;
}

/* Registered so they are numbers that can ease, not strings that snap. */
@property --light-hx { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --light-hy { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --light-gx { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --light-gy { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --light-glow { syntax: '<color>'; inherits: true; initial-value: transparent; }
@property --light-rim  { syntax: '<color>'; inherits: true; initial-value: transparent; }

/* --- the plate: a graphite object under one light ---------------------- */
.plate {
  position: relative;
  isolation: isolate;
  color: var(--light-glyph);
  --resurs-accent: var(--light-glyph-accent);
  background: none;
  box-shadow: none;
  overflow: visible;
  /* the light, relative to this plate, in px */
  --light-dx: calc(var(--lx, var(--light-sun-x)) - var(--ox, 0));
  --light-dy: calc(var(--ly, var(--light-sun-y)) - var(--oy, 0));
  --light-dist: hypot(var(--light-dx), var(--light-dy));
  /* the highlight leans toward the light, in percent of the face */
  --light-hx: clamp(-46, var(--light-dx) * 0.10, 46);
  --light-hy: clamp(-46, var(--light-dy) * 0.10, 46);
  transition: --light-hx 260ms var(--light-ease), --light-hy 260ms var(--light-ease);
}

/* the body: graphite, with the face turned toward the light catching it */
.plate::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background:
    radial-gradient(
      62% 62% at calc(50% + var(--light-hx) * 1%) calc(50% + var(--light-hy) * 1%),
      var(--light-face-lit) 0%, transparent 82%),
    linear-gradient(168deg, var(--light-body-top), var(--light-body-bottom));
  box-shadow:
    inset 0 1.5px 0 var(--light-bevel-light),
    inset 0 -1.5px 0 var(--light-bevel-dark),
    inset 0 0 0 1px var(--light-plate-ring);
}

/* the cast shadow: away from the light, longer and softer the further the
   light is, tight and dark when the lamp stands close. The constant 4px keeps
   it under the object even then - a lamp directly overhead still leaves a
   shadow, and a shadow with no direction reads as a smudge. */
.plate::after {
  content: '';
  position: absolute;
  inset: -3px;
  z-index: -2;
  border-radius: inherit;
  background: var(--light-shadow);
  transform: translate(
    calc(clamp(-18, var(--light-dx) * -0.020, 18) * 1px),
    calc((clamp(-18, var(--light-dy) * -0.020, 18) + 4) * 1px));
  filter: blur(calc(clamp(3, 2 + var(--light-dist) * 0.005, 11) * 1px));
  opacity: clamp(0.5, 1.05 - var(--light-dist) * 0.00030, 0.85);
  transition:
    transform 260ms var(--light-ease),
    filter 260ms var(--light-ease),
    opacity 320ms var(--light-ease) calc(var(--i, 0) * 18ms);
}
/* the glyph is cut into the graphite: a light stroke standing in a dark trench */
.plate .icon {
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 -1px 0 var(--light-glyph-trench));
}

/* scroll-in: the family's shadows settle in from the light, once */
.tile-grid:not([data-seen='true']) .plate::after,
.card-row:not([data-seen='true']) .plate::after { opacity: 0; }

/* --- the tile and the card: a quiet ground, a hairline on hover --------- */
/* The ground never answers the pointer. That is the fork's discipline: the
   family answers the light, never the one tile the pointer happens to be on. */
.tile, .card { position: relative; }
.tile::after, .card::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--light-hairline);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms var(--light-ease);
}
.tile:hover::after, .card:hover::after { opacity: 1; }
.tile:hover { box-shadow: inset 0 0 0 1px transparent; }
.tile:hover .plate { transform: none; }

/* --- the hero panel: cold glass under the same light ------------------- */
.glass {
  position: relative;
  isolation: isolate;
  background: linear-gradient(158deg, var(--light-glass-cool-top), var(--light-glass-cool-bottom));
  border-color: var(--light-glass-edge);
  backdrop-filter: blur(var(--light-glass-blur)) saturate(1.1);
  -webkit-backdrop-filter: blur(var(--light-glass-blur)) saturate(1.1);
  box-shadow:
    inset 0 1.5px 0 var(--light-panel-bevel),
    inset 0 -1.5px 0 var(--light-panel-under),
    inset 0 0 0 1px var(--light-panel-inner),
    var(--light-glass-cast);
  /* where the light sits on the panel, in percent: the sun at rest */
  --light-gx: calc(var(--px, var(--light-glass-sun-x)) * 100);
  --light-gy: calc(var(--py, var(--light-glass-sun-y)) * 100);
  --light-glow: var(--light-sun-warm);
  --light-rim: var(--light-sun-rim);
  transition:
    --light-gx 420ms var(--light-ease), --light-gy 420ms var(--light-ease),
    --light-glow 420ms var(--light-ease), --light-rim 420ms var(--light-ease);
}
.glass[data-lit='true'] {
  --light-glow: var(--light-lamp-cool);
  --light-rim: var(--light-lamp-rim);
}
/* the rim: one ring, white where it faces the light and dark where it turns
   away. A ring that only brightens says nothing about direction; this one is
   the panel's whole claim to being a solid thing under a sun. */
.glass::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  padding: 3px;
  background: radial-gradient(
    128% 150% at calc(var(--light-gx) * 1%) calc(var(--light-gy) * 1%),
    var(--light-rim) 0%, var(--light-rim) 26%, var(--light-rim-far) 84%);
  -webkit-mask: linear-gradient(var(--light-opaque) 0 0) content-box, linear-gradient(var(--light-opaque) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(var(--light-opaque) 0 0) content-box, linear-gradient(var(--light-opaque) 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
/* the light inside the glass: warm from the sun, cool from the lamp */
.glass::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(
    96% 124% at calc(var(--light-gx) * 1%) calc(var(--light-gy) * 1%),
    var(--light-glow) 0%, transparent 72%);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .plate, .plate::after, .tile::after, .card::after, .glass { transition: none; }
}
