/*  The light.
 *
 *  THE LAW, in one sentence: the light comes from beyond the horizon.
 *
 *  Every band on this site is drawn over the contours of the Mendrisiotto —
 *  the ground from Chiasso up to Lake Lugano, traced by ibex-atmosphere.js. If
 *  the page has a terrain then it has a horizon, and if it has a horizon then
 *  there is a source behind it, low and to the left. Everything else has to
 *  behave as though there were:
 *
 *    the ground has depth        every band takes the same source, from the
 *                                same direction, at the same size — fixed, not
 *                                a proportion of the band, or each section
 *                                would have its own window and the page would
 *                                have none
 *
 *    paper receives it           the light bands lift toward the source and
 *                                fall away from it, which is the whole
 *                                difference between a sheet of paper and a
 *                                coloured rectangle
 *
 *    the first band lights       the reader arrives into a room, not into a
 *                                photograph of one
 *
 *  AMPLITUDE IS THE ENTIRE DESIGN. Every value below is deliberately under the
 *  threshold at which a reader could name it. A visitor must never think «there
 *  is a gradient there»; they should only find the page hard to leave.
 *
 *  And none of the three is an aesthetic setting. Each is bounded by what the
 *  worst pair of colours on that kind of band can afford before it drops under
 *  WCAG AA — worked out by scripts/check_contrast.py, which reads this file and
 *  ibex-base.css rather than a number somebody retyped, and which the deploy
 *  runs before the restart.
 *
 *  WHERE THIS SITE DIFFERS FROM IBEX CAPITAL, and it is worth stating because
 *  the design is the same design. There the light is pressed right up against
 *  its ceiling: the peak on a dark band is 0.04 and leaves the smallest type at
 *  4.62:1, four per cent clear of the threshold, and a first draft at 0.058 had
 *  to be taken back because it measured 4.46:1. Here the same 0.04 would leave
 *  the worst pair at 7.05:1, because this palette's muted grey is 7.4:1 where
 *  Capital's is 4.9:1. There is room to go to 0.10 and stay compliant.
 *
 *  It does not. Contrast sets a ceiling; it does not choose a value. The light
 *  should read the same on both IBEX sites, which is most of the point of
 *  having a house standard at all, so the amplitude here is set by eye against
 *  Capital's and then checked — not set by what this palette could survive.
 *
 *  Nothing here costs layout. Every animated property is opacity or transform;
 *  everything else is a static gradient on a pseudo-element that the compositor
 *  paints once. Every movement has an off switch under prefers-reduced-motion,
 *  and the decoration disappears entirely under forced-colors.  */

:root {
  /*  The champagne, as components. --gold opened up and desaturated: a glow
   *  carries its hue over a large soft area, where the value that reads as
   *  metal in a hairline reads as a yellow spotlight. Falls back to its own
   *  value if the palette is ever missing.  */
  --lit-warm: var(--gold-lamp, 214, 190, 144);

  /*  Where the source is, and how big. Below the lower-left corner, and a size
   *  in pixels rather than per cent: a 3700px band and a 280px band are lit by
   *  the same window, which is what makes it read as one room.  */
  --lit-x: 18%;
  --lit-y: 104%;
  --lit-size: clamp(620px, 78vw, 1180px);

  --lit-dark:  0.050;  /* peak warmth on ink   → --ink-060   at 6.93:1 */
  --lit-paper: 0.060;  /* lift on paper        → can only add contrast */
  --lit-shade: 0.018;  /* fall-off, on paper   → --gold-deep at 4.76:1 */

  --lit-ease: cubic-bezier(.19, 1, .22, 1);
}

/* ---------------------------------------------------------------- the ground */

/*  isolation, and not merely position:relative, is what makes z-index:-1 mean
 *  "behind this band's content" instead of "behind the document". A band is
 *  already position:relative from the template, which is not a stacking
 *  context; the light would then escape upward and paint under the page.
 *
 *  z-index:-1 rather than 0 on purpose: at 0 the layer paints above any content
 *  that is not itself positioned, and a band whose text is not wrapped in a
 *  positioned element would have the wash laid over its words. At -1 the layer
 *  can only ever sit between the background and everything else.
 *
 *  [data-band] and not section[data-band]. The Insights masthead is a <header>
 *  and its prose column is a <div> — both carry the attribute, both are bands,
 *  and a selector naming the element would have lit ten pages out of twelve.  */
[data-band] { isolation: isolate; }

[data-band]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/*  Dark: the source itself, seen. Warm, wide, and stopped well before the far
 *  corner so the band still has a dark side. The stops carry the presence the
 *  peak is not allowed to — contrast is set by the brightest point and nothing
 *  else, so widening the falloff lights more of the band for free.  */
[data-band="dark"]::before {
  background: radial-gradient(
    var(--lit-size) circle at var(--lit-x) var(--lit-y),
    rgba(var(--lit-warm), var(--lit-dark)),
    rgba(var(--lit-warm), calc(var(--lit-dark) * 0.42)) 40%,
    transparent 74%
  );
}

/*  Paper: the source, not seen. Two gradients — the near corner lifted toward
 *  white, the far corner given a breath of the ink. One alone reads as a tint;
 *  the pair reads as a sheet under a lamp.  */
[data-band="light"]::before {
  background:
    radial-gradient(
      var(--lit-size) circle at var(--lit-x) var(--lit-y),
      rgba(255, 253, 248, var(--lit-paper)),
      transparent 62%
    ),
    radial-gradient(
      var(--lit-size) circle at 86% -10%,
      rgba(26, 24, 23, var(--lit-shade)),
      transparent 64%
    );
}

/* ------------------------------------------------------------------ the dawn */

/*  The first band of any page is the one the reader arrives in, so it is the
 *  one that lights. The light rises from below its lower edge and settles.
 *
 *  What deliberately does NOT happen here: the type does not fade in. Every
 *  template fades its headline up on load, it is the single commonest tell of a
 *  template, and it delays the largest paint on the page for the sake of an
 *  effect that says «watch me arrive». The words are there in the first frame
 *  and the room lights around them. That is both the more confident reading and
 *  the faster one.
 *
 *  Scoped to html.ibex-js, like everything else that hides something: if
 *  scripts never run, the class is never set, and the light is simply already
 *  on.  */
@media (prefers-reduced-motion: no-preference) {
  html.ibex-js main > div > [data-band]:first-child::before,
  html.ibex-js main > [data-band]:first-child::before {
    opacity: 0;
    transform: translate3d(0, 46px, 0);
    animation:
      ibex-dawn 1900ms var(--lit-ease) 80ms forwards,
      ibex-breathe 15s ease-in-out 2100ms infinite;
  }
  @keyframes ibex-dawn { to { opacity: 1; transform: none; } }

  /*  The hero breathes. Fifteen seconds, and an amplitude of fourteen per cent
   *  of an already invisible glow — a peak-to-trough difference of 0.007 alpha,
   *  which cannot be seen frame to frame and can be felt over a minute. It is
   *  the difference between a photograph of a room and a room.  */
  @keyframes ibex-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.86; } }
}

/* ------------------------------------------------------------------ the metal */

/*  Gold set large, on a dark ground, blooms. No offset and a wide radius: this
 *  is a reflection, not a shadow and not a neon. At 0.16 it is invisible when
 *  looked for and does its work when not.
 *
 *  Only on the dark bands, and only on the two things this site sets large in
 *  the accent: the figure in a statistics block and the kicker over a hero. On
 *  paper the same treatment would be a smudge — which is exactly what light
 *  does and does not do on the two materials.  */
[data-band="dark"] [data-figure],
[data-band="dark"] [data-herofigure] {
  text-shadow: 0 0 34px rgba(var(--lit-warm), 0.16);
}

/* -------------------------------------------------------------- micro-craft */

/*  Selection was one champagne for the whole site. On a dark ground that is
 *  right; on paper the same value is a wash of pale yellow behind dark type,
 *  which looks like a highlighter. Paper gets the deep brass at low strength
 *  instead — the same metal, in the light that band is in.  */
[data-band="light"] ::selection {
  background: rgba(126, 97, 40, 0.17);
  color: inherit;
}

/*  The scrollbar is chrome the browser draws and almost every site leaves at
 *  the default, which on a dark page is a bright grey slab down the right edge.
 *  Thin, warm, and the same ink as everything else.  */
@supports selector(::-webkit-scrollbar) {
  html::-webkit-scrollbar { width: 11px; height: 11px; }
  html::-webkit-scrollbar-track { background: var(--ink-900); }
  html::-webkit-scrollbar-thumb {
    background: rgba(var(--lit-warm), 0.20);
    border: 3px solid var(--ink-900);
    border-radius: 6px;
  }
  html::-webkit-scrollbar-thumb:hover { background: rgba(var(--lit-warm), 0.34); }
}
html { scrollbar-width: thin; scrollbar-color: rgba(167, 159, 150, 0.34) var(--ink-900); }

/* -------------------------------------------------------- what the reader wants */

/*  Reduced motion: the light is still there and still models the page, because
 *  it does not move. Nothing rises, nothing breathes — every element is simply
 *  in its final state, which is the state the whole file was designed to arrive
 *  at.  */
@media (prefers-reduced-motion: reduce) {
  [data-band]::before { opacity: 1; transform: none; animation: none; }
}

/*  High contrast: every decorative surface off, and nothing that carried
 *  meaning goes with it — the glow was never information.  */
@media (forced-colors: active) {
  [data-band]::before { display: none; }
  [data-band="dark"] [data-figure],
  [data-band="dark"] [data-herofigure] { text-shadow: none; }
}

/*  Print: paper is already lit.  */
@media print {
  [data-band]::before { display: none !important; }
}
