/*
 * Liquid Glass for newcanaan.town (D42). Active only with `[design] glass = "lab"`
 * (data-glass="lab" on <html>). Five materials, each with a role, from quiet to active:
 *
 *   L1 regular  About, Availability, Contact   reading panels: light frost, dark text
 *   L2 rim      404 hero                       the densest fill, for small text and links,
 *                                              with a lit rim and thickness
 *   L4 clear    Hero                           the one focal surface: dark dim, white text,
 *                                              the photo shows through
 *   L5 capsule  the mail button                the only accent tint; hover, press, shimmer
 *   L6 lens     the header pill                floats and bends what is behind it
 *
 * The disclaimer is not a panel: it is plain text in a footer, on a solid colour that the
 * photo fades into (see "Footer" below).
 *
 * Reading text sits on quiet panels. The optics (rim, lens, motion) go to what you can use.
 *
 * crates/sitegen/src/contrast.rs (check_lab) mirrors the opacities in the first block of
 * tokens below. It checks every material against the worst case, a black or a white photo
 * pixel, so these numbers are the lowest that pass. Change them together; a unit test keeps
 * them in sync. Blur, saturate and the lens only move a pixel to another colour inside the
 * same range, so the guard does not model them. There is no global scrim in the lab, so all
 * text must sit on one of these materials.
 */

/* The hover shine moves along the capsule. A registered property can be animated. */
@property --lg-shine {
  syntax: "<percentage>";
  inherits: false;
  initial-value: -30%;
}

/* No wash over the photo in the lab: the panels carry the contrast. */
:root[data-glass="lab"][data-bg="photo"] { --scrim-strength: 0%; }

:root[data-glass="lab"] {
  --lg-regular-a:     .56;
  --lg-rim-a:         .84;
  --lg-clear-dim:     .56;
  --lg-capsule-dim:   .62;
  --lg-capsule-tint:  .28;
  --lg-capsule-sheen: .10;
  --lg-lens-dim:      .58;

  --lg-fill-rgb:   255 255 255;
  --lg-rim-hi:     rgb(255 255 255 / .95);
  --lg-rim-lo:     rgb(255 255 255 / .14);
  --lg-edge-light: rgb(255 255 255 / .55);
  --lg-hairline:   rgb(255 255 255 / .45);
  --lg-drop:       rgb(0 0 0 / .14);
  --lg-blur:       24px;

  /* Footer: the photo fades into the page colour over --lg-fade. The text must start below
     that, so --lg-footer-top must be at least --lg-fade. A unit test checks it. */
  --lg-fade:       3rem;
  --lg-footer-top: 4rem;
}

@media (prefers-color-scheme: dark) {
  :root[data-glass="lab"] {
    --lg-regular-a:  .68;
    --lg-rim-a:      .90;
    --lg-fill-rgb:   28 32 39;
    --lg-rim-hi:     rgb(255 255 255 / .55);
    --lg-rim-lo:     rgb(255 255 255 / .08);
    --lg-edge-light: rgb(255 255 255 / .22);
    --lg-hairline:   rgb(255 255 255 / .16);
    --lg-drop:       rgb(0 0 0 / .40);
  }
}

/* --- Base: blur, saturate and a hairline edge ------------------------------------------- */
.lg {
  position: relative;
  isolation: isolate;
  border: 1px solid var(--lg-hairline);
  border-radius: var(--radius-lg);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(180%);
  backdrop-filter: blur(var(--lg-blur)) saturate(180%);
  box-shadow: 0 8px 24px -8px var(--lg-drop);
}

/* A control that sits inside a glass section. A backdrop-filter inside another one sees only
   its parent, not the photo, so the parent drops its own filter and keeps its dim. */
.lg-host {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* --- Optics: lit rim, thickness, contact shadow ----------------------------------------- */
.lg-optics {
  border-color: transparent;
  box-shadow:
    0 1px 2px var(--lg-drop),
    0 14px 28px -10px var(--lg-drop),
    inset 0 1px 1px var(--lg-edge-light),
    inset 0 -1px 1px rgb(255 255 255 / .10),
    inset 0 0 12px rgb(255 255 255 / .06);
}
/* The rim is a gradient ring cut out with a mask: bright at the top left and bottom right,
   faint in between, like light caught on the edge of a thick pane. */
.lg-optics::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 1;
  padding: 1.5px;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(135deg,
    var(--lg-rim-hi) 0%, var(--lg-rim-lo) 28%, transparent 55%,
    var(--lg-rim-lo) 78%, var(--lg-rim-hi) 100%);
  -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 exclude, linear-gradient(#000 0 0);
}

/* --- L1 regular, L2 rim: light frost, dark text ----------------------------------------- */
.lg-regular { background: rgb(var(--lg-fill-rgb) / var(--lg-regular-a)); }
/* Small grey text and links need the densest fill. */
.lg-rim {
  --lg-blur: 28px;
  background: rgb(var(--lg-fill-rgb) / var(--lg-rim-a));
}

/* --- L4 clear: dark dim, light text ----------------------------------------------------- */
.lg-clear,
.lg-capsule,
.lg-lens { color: #fff; }
.lg-clear p { color: inherit; }
.lg-clear {
  --lg-blur: 6px;
  background: rgb(0 0 0 / var(--lg-clear-dim));
}

/* --- L5 capsule: a glass button with states --------------------------------------------- */
.lg-capsule {
  --lg-blur: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .75rem 1.5rem;
  border-radius: 999px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  overflow-wrap: anywhere;
  background:
    linear-gradient(
      color-mix(in srgb, var(--accent) calc(var(--lg-capsule-tint) * 100%), transparent),
      color-mix(in srgb, var(--accent) calc(var(--lg-capsule-tint) * 100%), transparent)),
    rgb(0 0 0 / var(--lg-capsule-dim));
  transition:
    transform .25s cubic-bezier(.2, .8, .2, 1),
    box-shadow .25s ease,
    --lg-shine .9s ease;
}
/* The shine is a faint white band. Its peak is the sheen opacity the guard counts. */
.lg-capsule::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(105deg,
    transparent calc(var(--lg-shine) - 18%),
    rgb(255 255 255 / var(--lg-capsule-sheen)) var(--lg-shine),
    transparent calc(var(--lg-shine) + 18%));
}
.lg-capsule:hover {
  --lg-shine: 130%;
  --lg-rim-hi: rgb(255 255 255 / 1);
  transform: translateY(-1px);
  box-shadow:
    0 2px 4px var(--lg-drop),
    0 18px 32px -10px var(--lg-drop),
    inset 0 1px 1px var(--lg-edge-light),
    inset 0 0 12px rgb(255 255 255 / .06);
}
.lg-capsule:active { transform: scale(.97); }
.lg-capsule:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
  box-shadow: 0 0 0 7px rgb(0 0 0 / .55);
}
.lg-contact-note { margin-bottom: 1rem; }

/* --- L6 lens: a floating pill that bends what is behind it ------------------------------ */
:root[data-glass="lab"] .site-header {
  position: sticky;
  top: .5rem;
  z-index: 5;
  pointer-events: none;   /* the transparent strip must not block the panels under it */
}
:root[data-glass="lab"] .site-name { pointer-events: auto; }
.lg-lens {
  --lg-blur: 3px;
  background: rgb(0 0 0 / var(--lg-lens-dim));
}
/* The SVG filter that does the bending is inline in base.html (a filter must be in the
   document, and the CSP allows no data: URLs). It hides at zero size, not display: none,
   because a display: none filter does not apply in every browser. */
.lg-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* Chromium bends the real backdrop with an SVG filter in backdrop-filter. WebKit and Gecko
   do not support that, and `@supports` cannot test for it, so this switches on a Chromium-only
   property instead. Needs checking in Chrome: not tested here. */
@supports (-webkit-app-region: none) {
  .lg-lens {
    -webkit-backdrop-filter: url(#lg-lens) blur(var(--lg-blur)) saturate(190%);
    backdrop-filter: url(#lg-lens) blur(var(--lg-blur)) saturate(190%);
  }
}
/* Everyone else: a copy of the page photo, lined up with the real one through a fixed
   attachment, with the same filter on the copy and the same dim on top. Only where a fixed
   background works (not iOS), otherwise the lens stays the plain pill. */
@supports not (-webkit-app-region: none) {
  @media (hover: hover) and (pointer: fine) {
    .lg-lens::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: -1;
      border-radius: inherit;
      background:
        linear-gradient(rgb(0 0 0 / var(--lg-lens-dim)), rgb(0 0 0 / var(--lg-lens-dim))),
        var(--bg-image) center / cover no-repeat fixed;
      filter: url(#lg-lens);
    }
  }
}

/* --- Footer: plain text on a solid colour the photo fades into -------------------------- */
/* No panel, border or glass. The text is --ink on --surface, so its contrast does not depend
   on the photo; the guard checks it as the `footer` material. The footer sticks to the bottom
   of short pages. It only gets the fade when there is a disclaimer to show. */
:root[data-glass="lab"] body {
  display: flex;
  flex-direction: column;
}
:root[data-glass="lab"] main { flex: 1 0 auto; }
:root[data-glass="lab"] .site-footer {
  margin-top: auto;
}
:root[data-glass="lab"] .site-footer:has(.lg-fine) {
  width: auto;
  margin-inline: 0;
  padding: var(--lg-footer-top) 1.25rem 2rem;
  background: linear-gradient(
    color-mix(in srgb, var(--surface) 0%, transparent),
    var(--surface) var(--lg-fade));
}
.lg-fine {
  max-width: 44rem;
  margin-inline: auto;
  color: var(--ink);
  font-size: .8125rem;
  line-height: 1.5;
  text-align: center;
}

/* --- Fallbacks -------------------------------------------------------------------------- */
/* Reduce transparency: denser layers (only more contrast), no backdrop filter, no lens copy.
   Reduce motion: no movement. */
@media (prefers-reduced-transparency: reduce) {
  :root[data-glass="lab"] {
    --lg-regular-a:   .96;
    --lg-rim-a:       .96;
    --lg-clear-dim:   .92;
    --lg-capsule-dim: .92;
    --lg-lens-dim:    .92;
  }
  .lg,
  .lg-lens {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .lg-lens::after { content: none; }
}
@media (prefers-reduced-motion: reduce) {
  .lg-capsule { transition: none; }
  .lg-capsule:hover,
  .lg-capsule:active { transform: none; }
  .lg-capsule:hover { --lg-shine: -30%; }
}
