/* ==========================================================================
   Glass & atmosphere — translucent surfaces, ambient light fields, grain,
   and the image placeholder component.

   Glass only reads as glass when there is something behind it, so every
   glass surface sits over an ambient light field (.section--ambient) or the
   night palette. Backdrop filters are expensive: keep them to a handful of
   elements per viewport.
   ========================================================================== */

/* --- Ambient light fields ------------------------------------------------ */

.section--ambient,
.hero--ambient {
  position: relative;
  isolation: isolate;
  /* The light fields deliberately bleed past the section edges, so clip them.
     `clip` rather than `hidden` keeps the sticky header working. */
  overflow: clip;
}

.section--ambient::before,
.section--ambient::after,
.hero--ambient::before {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(70px);
}

/* Warm brass wash, upper right. */
.section--ambient::before,
.hero--ambient::before {
  inline-size: min(38rem, 62vw);
  aspect-ratio: 1;
  inset-block-start: -14%;
  inset-inline-end: -8%;
  background: radial-gradient(
    circle,
    oklch(84% 0.09 82 / 0.55),
    oklch(84% 0.09 82 / 0) 68%
  );
}

/* Cool lens-tint wash, lower left. */
.section--ambient::after {
  inline-size: min(32rem, 58vw);
  aspect-ratio: 1;
  inset-block-end: -18%;
  inset-inline-start: -10%;
  background: radial-gradient(
    circle,
    oklch(82% 0.07 232 / 0.42),
    oklch(82% 0.07 232 / 0) 68%
  );
}

.on-night.section--ambient::before {
  background: radial-gradient(
    circle,
    oklch(62% 0.11 78 / 0.34),
    oklch(62% 0.11 78 / 0) 68%
  );
}

.on-night.section--ambient::after {
  background: radial-gradient(
    circle,
    oklch(58% 0.1 244 / 0.36),
    oklch(58% 0.1 244 / 0) 68%
  );
}

/* --- Glass surface ------------------------------------------------------- */

.glass {
  position: relative;
  background: linear-gradient(
    148deg,
    oklch(100% 0 0 / 0.66),
    oklch(100% 0 0 / 0.3) 46%,
    oklch(100% 0 0 / 0.44)
  );
  backdrop-filter: blur(18px) saturate(1.6);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  border: 1px solid oklch(100% 0 0 / 0.72);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.75),
    inset 0 -1px 0 oklch(100% 0 0 / 0.25),
    0 22px 48px -28px oklch(21% 0.018 258 / 0.5);
  overflow: hidden;
}

/* Specular sweep across the top-left corner. */
.glass::before {
  content: "";
  position: absolute;
  inset-block-start: -60%;
  inset-inline-start: -30%;
  inline-size: 80%;
  block-size: 160%;
  background: linear-gradient(
    100deg,
    oklch(100% 0 0 / 0.5),
    oklch(100% 0 0 / 0) 62%
  );
  transform: rotate(-14deg);
  pointer-events: none;
  opacity: 0.7;
  transition: transform var(--duration-slow) var(--ease-out-expo),
    opacity var(--duration-normal) var(--ease-standard);
}

.glass:hover::before {
  transform: rotate(-14deg) translateX(14%);
  opacity: 1;
}

.on-night .glass,
.glass.on-night {
  background: linear-gradient(
    148deg,
    oklch(100% 0 0 / 0.11),
    oklch(100% 0 0 / 0.03) 46%,
    oklch(100% 0 0 / 0.07)
  );
  border-color: oklch(100% 0 0 / 0.16);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.16),
    0 30px 60px -30px oklch(0% 0 0 / 0.75);
}

.on-night .glass::before {
  background: linear-gradient(
    100deg,
    oklch(100% 0 0 / 0.14),
    oklch(100% 0 0 / 0) 62%
  );
}

/* A brass hairline along the top edge — the "chic" detail. */
.glass--edge::after {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 12%;
  block-size: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--color-brass) 45%,
    transparent
  );
  opacity: 0.8;
  pointer-events: none;
}

/* Glass needs its content above the sheen. */
.glass > * {
  position: relative;
  z-index: 1;
}

@supports not (backdrop-filter: blur(4px)) {
  .glass {
    background: color-mix(in oklab, var(--color-paper) 88%, transparent);
  }

  .on-night .glass {
    background: color-mix(in oklab, var(--color-night-raised) 88%, transparent);
  }
}

/* --- Existing components, glassed --------------------------------------- */

.card,
.branch,
.hero__badge,
.framed__plate,
.form-panel {
  background: linear-gradient(
    148deg,
    oklch(100% 0 0 / 0.62),
    oklch(100% 0 0 / 0.26) 46%,
    oklch(100% 0 0 / 0.4)
  );
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border: 1px solid oklch(100% 0 0 / 0.7);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.7),
    0 18px 40px -26px oklch(21% 0.018 258 / 0.45);
}

.on-night .card,
.on-night .branch,
.on-night .form-panel {
  background: linear-gradient(
    148deg,
    oklch(100% 0 0 / 0.1),
    oklch(100% 0 0 / 0.03) 46%,
    oklch(100% 0 0 / 0.06)
  );
  border-color: oklch(100% 0 0 / 0.15);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.14),
    0 28px 56px -30px oklch(0% 0 0 / 0.7);
}

.card:hover,
.branch:hover {
  border-color: oklch(100% 0 0 / 0.92);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.85),
    0 26px 52px -24px oklch(21% 0.018 258 / 0.5);
}

.on-night .card:hover,
.on-night .branch:hover {
  border-color: color-mix(in oklab, var(--color-brass-glow) 45%, transparent);
}

.form-panel {
  padding: clamp(1.25rem, 0.9rem + 1.6vw, 2.25rem);
  border-radius: var(--radius-lg);
}

/* Chips pick up a lighter version of the same material. */
.chip {
  background: oklch(100% 0 0 / 0.42);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-color: oklch(100% 0 0 / 0.65);
}

/* Brand tiles on the dark grid get an interior glow rather than a border. */
.brand-tile {
  transition: background-color var(--duration-normal) var(--ease-standard);
}

.brand-tile:hover {
  background: linear-gradient(
    155deg,
    color-mix(in oklab, var(--color-surface) 92%, oklch(100% 0 0)),
    var(--color-surface)
  );
}

.on-night .brand-tile:hover {
  background: linear-gradient(
    155deg,
    oklch(100% 0 0 / 0.07),
    oklch(100% 0 0 / 0.01)
  );
}

/* The sticky header is the one piece of glass that is always on screen. */
.site-header {
  background: linear-gradient(
    to bottom,
    oklch(97.6% 0.008 85 / 0.9),
    oklch(97.6% 0.008 85 / 0.7)
  );
  backdrop-filter: blur(20px) saturate(1.8);
  -webkit-backdrop-filter: blur(20px) saturate(1.8);
}

.site-header[data-scrolled="true"] {
  background: linear-gradient(
    to bottom,
    oklch(97.6% 0.008 85 / 0.96),
    oklch(97.6% 0.008 85 / 0.82)
  );
  box-shadow: 0 1px 0 var(--color-line), 0 18px 40px -34px oklch(21% 0.018 258 / 0.6);
}

/* --- Image placeholders -------------------------------------------------- */

/*
  Drop a real image in and it takes over automatically:

    <figure class="shot shot--portrait" data-shot="Birr practice interior">
      <img src="/media/birr.avif" alt="…" width="1200" height="1500" loading="lazy" />
    </figure>
*/

.shot {
  position: relative;
  display: block;
  margin: 0;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(
      152deg,
      oklch(94% 0.02 84),
      oklch(89% 0.03 232) 55%,
      oklch(92% 0.02 320)
    ),
    var(--color-bone-deep);
  border: 1px solid var(--color-line);
  box-shadow: var(--shadow-raise);
  isolation: isolate;
}

.shot--portrait {
  aspect-ratio: 3 / 4;
}

.shot--wide {
  aspect-ratio: 16 / 9;
}

.shot--square {
  aspect-ratio: 1;
}

.shot--tall {
  aspect-ratio: 2 / 3;
}

.shot img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  z-index: 2;
}

/* Optical rings, so an empty slot still looks like part of the design. */
.shot::before {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 58%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 1px solid oklch(100% 0 0 / 0.55);
  box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.18),
    inset 0 0 40px oklch(100% 0 0 / 0.4);
}

.shot::after {
  content: attr(data-shot);
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding: var(--space-sm) var(--space-md);
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
  background: linear-gradient(
    to top,
    oklch(100% 0 0 / 0.7),
    oklch(100% 0 0 / 0)
  );
}

/*
  Catalogue cut-outs arrive on a white studio background, which would read as a
  white rectangle inside a tinted panel. `shot--product` gives them a paper
  ground, room to breathe, and `contain` so the frame floats rather than crops.
*/
.shot--product {
  background: var(--color-paper);
  padding: clamp(0.75rem, 0.3rem + 1.6vw, 1.75rem);
}

.shot--product img {
  position: static;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  /* Multiply drops the studio white into the paper ground. A drop-shadow would
     trace the image's rectangle, so the panel carries the depth instead. */
  mix-blend-mode: multiply;
}

.on-night .shot--product {
  background: oklch(96% 0.004 85);
}

.on-night .shot {
  background: linear-gradient(
    152deg,
    oklch(28% 0.02 258),
    oklch(24% 0.03 244) 55%,
    oklch(27% 0.02 300)
  );
  border-color: var(--color-line-night);
}

.on-night .shot::before {
  border-color: oklch(100% 0 0 / 0.2);
  box-shadow: inset 0 0 50px oklch(100% 0 0 / 0.06);
}

.on-night .shot::after {
  color: var(--color-night-mute);
  background: linear-gradient(to top, oklch(0% 0 0 / 0.55), oklch(0% 0 0 / 0));
}

/* Once a real image is present the caption plate and rings get out of the way. */
.shot:has(img)::before {
  display: none;
}

.shot:has(img)::after {
  content: "";
  padding: 0;
}

/* --- Editorial media compositions ---------------------------------------- */

.shot-stack {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
}

.shot-stack .shot:nth-child(2) {
  margin-block-start: var(--space-xl);
}

.shot-trio {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/* Media panel with a glass caption card floating over the lower corner. */
.framed {
  position: relative;
}

.framed__plate {
  position: absolute;
  /* Clears the placeholder's caption strip; once a real image is dropped in
     the caption disappears and the plate simply sits above the lower edge. */
  inset-block-end: 3.5rem;
  inset-inline: var(--space-md);
  display: grid;
  gap: 0.2rem;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  z-index: 3;
}

.framed__plate strong {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 400;
  letter-spacing: -0.01em;
}

.framed__plate span {
  font-size: var(--text-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
}

@media (min-width: 48rem) {
  .framed__plate {
    inset-inline: auto var(--space-md);
    inline-size: max-content;
    max-inline-size: 70%;
  }

  /* A product shot is centred in its panel, so a plate placed inside would
     land on the frame. Hang it off the lower-left corner instead. */
  .framed:has(.shot--product) .framed__plate {
    inset-block-end: -1.5rem;
    inset-inline: -1.75rem auto;
  }
}

/* --- Grain --------------------------------------------------------------- */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce) {
  .glass::before {
    transition: none;
  }
}
