/* AQcredix — the glass layer.
 *
 * WHAT THIS IS. One surface treatment for every box that holds information:
 * stat tiles, cards, tables, modals, form fields, option buttons. It sits on
 * top of the existing token system and changes only how a surface is PAINTED —
 * no layout, no spacing, no type. That is deliberate: a visual pass that also
 * moves things is impossible to review and impossible to back out.
 *
 * WHY IT WORKS HERE AND NOT EVERYWHERE. Glass is a lens. Over a flat colour it
 * renders as a slightly lighter rectangle and looks like a mistake. It only
 * reads as glass when something is moving behind it, and this site already has
 * that: the WebGL vortex on <body data-bg>. The blur is sampling that. On a
 * page with no background, the fallback below takes over instead.
 *
 * THE LEGIBILITY RULE, which outranks the look. This is a clinical tool. A
 * nurse reads it mid-shift on a ward tablet with the screen dimmed. So the
 * translucency is capped well below the point where contrast suffers: every
 * text colour on every glass surface here still clears 4.5:1, and the tint is
 * carried by an opaque underlay rather than by the blur alone. Glass that you
 * have to squint through is a failed design, not a bold one.
 *
 * THREE WAYS IT DEGRADES, all deliberate:
 *   - no backdrop-filter support     -> solid --bg-elevated, unchanged from today
 *   - prefers-reduced-transparency   -> solid, for people who asked for solid
 *   - prefers-reduced-motion         -> no hover lift, no sheen, no reveal
 */

/* ============================================================
   1. THE TOKENS
   Two layers per surface: an opaque floor that guarantees contrast, and a
   translucent film above it that does the refracting. Splitting them is what
   lets the blur be strong without the text going soft.
   ============================================================ */
/* ONE HUE, AND IT IS THE ONE ALREADY ON THE SITE.
   The palette here is indigo and nothing else: #2743C9 on paper, #4C6FFF on
   black, the same blue the globe is drawn in. Saturation is held near 100%
   on purpose. saturate() is what turns whatever sits behind a panel into
   something vivid, and pushing it is how glassmorphism ends up looking like a
   festival poster — every stray colour behind the page gets amplified and the
   surface stops belonging to the theme. Held at 106–112%, glass reads as
   tinted glass rather than as a light show. */
:root {
  --glass-floor:      rgba(255, 255, 255, .78);
  --glass-film:       rgba(39, 67, 201, .045);   /* the brand blue, barely there */
  --glass-edge:       rgba(15, 23, 42, .11);
  --glass-specular:   rgba(255, 255, 255, .70);
  --glass-blur:       16px;
  --glass-sat:        106%;
  --glass-radius:     16px;
  /* Neutral shadow, not a coloured glow. A blue-tinted drop shadow under every
     panel is the other half of the carnival problem. */
  --glass-lift:       0 1px 2px rgba(15, 23, 42, .05), 0 14px 34px -24px rgba(15, 23, 42, .26);
  --glass-lift-hover: 0 2px 5px rgba(15, 23, 42, .07), 0 22px 48px -26px rgba(15, 23, 42, .32);
}

/* DARK. True black ground, so the film is a dusting and the edge does the
   shape-making — a white border at 9% over #000 is what separates one panel
   from the next without drawing a box around it. The lift is near-black rather
   than a blue bloom: the panel should sit ON the dark, not glow out of it. */
:root[data-theme="dark"] {
  --glass-floor:      rgba(10, 13, 24, .62);
  --glass-film:       rgba(76, 111, 255, .045);
  --glass-edge:       rgba(237, 241, 248, .09);
  --glass-specular:   rgba(237, 241, 248, .10);
  --glass-blur:       18px;
  --glass-sat:        112%;
  --glass-lift:       0 1px 2px rgba(0, 0, 0, .6), 0 16px 38px -24px rgba(0, 0, 0, .9);
  --glass-lift-hover: 0 2px 6px rgba(0, 0, 0, .65), 0 24px 52px -26px rgba(0, 0, 0, .95);
}

/* ============================================================
   2. THE SURFACE
   ============================================================ */
.glass {
  position: relative;
  border-radius: var(--glass-radius);
  background-color: var(--glass-floor);
  background-image: linear-gradient(160deg, var(--glass-film), transparent 62%);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lift);
  /* The inset line along the top edge is the single detail that reads as a
     physical pane catching light. Without it the panel looks like a flat
     translucent div, which is what most glassmorphism on the web actually is. */
  --glass-inset: inset 0 1px 0 var(--glass-specular);
  box-shadow: var(--glass-lift), var(--glass-inset);
  transition: box-shadow .28s cubic-bezier(.22, 1, .36, 1),
              transform   .28s cubic-bezier(.22, 1, .36, 1),
              border-color .28s ease;
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .glass {
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}

/* No support: the surface people have today. Nothing looks broken, it just
   looks like it did last week. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background-color: var(--bg-elevated);
    background-image: none;
  }
}

/* ============================================================
   3. INTERACTION
   The lift is small on purpose. A 2px rise and a brighter edge is enough to
   say "this responds"; the 8px hover pop that tutorials reach for makes a
   dense page of records feel like it is breathing at you.
   ============================================================ */
.glass-hover:hover {
  transform: translateY(-2px);
  box-shadow: var(--glass-lift-hover), var(--glass-inset);
  /* A quarter of the brand blue into the edge, not a half. Enough to say the
     row is live under the cursor; not enough to light up a whole register. */
  border-color: color-mix(in srgb, var(--brand-2) 26%, var(--glass-edge));
}
.glass-hover:active { transform: translateY(0); }

.glass:focus-within {
  border-color: color-mix(in srgb, var(--brand-2) 55%, var(--glass-edge));
}

/* A sheen that crosses once on hover. Pointer-events off so it can never eat
   a click, and clipped to the panel so it cannot bleed over a neighbour. */
.glass-sheen { overflow: hidden; }
.glass-sheen::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%,
              var(--glass-specular) 50%, transparent 62%);
  opacity: 0;
  transform: translateX(-60%);
  transition: opacity .2s ease;
}
.glass-sheen:hover::after {
  opacity: .30;
  animation: glass-sweep .75s cubic-bezier(.22, 1, .36, 1) 1;
}
@keyframes glass-sweep {
  from { transform: translateX(-60%); }
  to   { transform: translateX(60%); }
}

/* ============================================================
   4. ENTRANCE
   Panels settle in rather than appearing. Driven by a class the page adds
   when the element scrolls into view, so nothing animates off-screen and
   nothing animates twice.
   ============================================================ */
.glass-in { opacity: 0; transform: translateY(14px) scale(.985); }
.glass-in.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .55s cubic-bezier(.22, 1, .36, 1),
              transform .55s cubic-bezier(.22, 1, .36, 1);
}
/* Stagger, so a grid of tiles arrives as a group rather than a volley. Capped
   at six: beyond that the last card is waiting long enough to feel broken. */
.glass-in.is-in:nth-child(2) { transition-delay: .06s; }
.glass-in.is-in:nth-child(3) { transition-delay: .12s; }
.glass-in.is-in:nth-child(4) { transition-delay: .18s; }
.glass-in.is-in:nth-child(5) { transition-delay: .24s; }
.glass-in.is-in:nth-child(6) { transition-delay: .30s; }

/* ============================================================
   5. FIELDS
   The ask was "all the placeholders", and a field is where glass most has to
   earn its place: it must still look like something you can type into.
   The floor is raised and the edge is stronger than on a card, because an
   input that reads as a decorative panel does not get filled in.
   ============================================================ */
.glass-field {
  border-radius: 12px;
  background-color: color-mix(in srgb, var(--glass-floor) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--glass-edge) 100%, transparent);
  box-shadow: inset 0 1px 0 var(--glass-specular);
  color: var(--fg);
  transition: border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .glass-field {
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
  }
}
.glass-field::placeholder { color: var(--fg-faint); opacity: 1; }
.glass-field:hover { border-color: color-mix(in srgb, var(--brand-2) 28%, var(--glass-edge)); }
.glass-field:focus {
  outline: none;
  border-color: var(--brand-2);
  box-shadow: inset 0 1px 0 var(--glass-specular),
              0 0 0 3px color-mix(in srgb, var(--brand-2) 22%, transparent);
}

/* ============================================================
   6. ACCESSIBILITY AND COST
   ============================================================ */

/* Somebody who has asked their system for less transparency has usually asked
   because transparency makes text hard for them. Honour it completely — not a
   reduced blur, no blur. */
@media (prefers-reduced-transparency: reduce) {
  .glass, .glass-field {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    background-color: var(--bg-elevated) !important;
    background-image: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .glass, .glass-in, .glass-in.is-in { transition: none !important; }
  .glass-hover:hover { transform: none; }
  .glass-sheen::after { display: none; }
  .glass-in { opacity: 1; transform: none; }
}

/* PHONES AND TABLETS.
   backdrop-filter is the most expensive thing on this page and the cost scales
   with blur radius and with how many panels are on screen at once. A ward
   tablet showing forty audit rows cannot afford an 18px blur forty times, so
   the radius drops and the lift goes flat. It still reads as glass; it just
   stops costing a frame. */
@media (max-width: 900px) {
  :root { --glass-blur: 12px; --glass-radius: 14px; }
  :root[data-theme="dark"] { --glass-blur: 13px; }
  .glass-sheen::after { display: none; }   /* a sweep nobody hovers on a phone */
}
@media (max-width: 560px) {
  :root { --glass-blur: 9px; --glass-radius: 13px; }
  :root[data-theme="dark"] { --glass-blur: 10px; }
  .glass-hover:hover { transform: none; }  /* hover on touch is a stuck state */
}

/* Very long lists opt out of the blur entirely and keep only the look. Past
   roughly thirty simultaneous blurred surfaces even a desktop drops frames
   while scrolling, and a register is exactly that case. */
.glass-flat, .glass-flat .glass {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background-color: var(--bg-elevated);
}

/* Printing renders glass as muddy grey. Registers and checklists get printed
   and taken to committee, so print gets plain paper. */
@media print {
  .glass, .glass-field {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    background: #fff !important;
    border: 1px solid #ccc !important;
    box-shadow: none !important;
  }
}
