/* Home page hero
   The headline changes the protected word (brand, invention, design, ideas)
   twice through, then settles, and a limestone foundation stone, carved with
   the monogram, the name and EST. MCMXLVII, is lit by the visitor's pointer.
   On phones and tablets a slow sun crosses it once instead. Builds on .hero,
   .hero-grid, .hero-title, .hero-lead, .hero-actions and .facts in styles.css. */

/* ------------------------------------------------------------ section */
/* The hero's ground. The intro paints the same ground (styles.css, .intro),
   laid over this box by src/intro.js, so when it lifts only the ink goes. */
:root {
  --hs-ground:
    radial-gradient(760px 620px at 76% 40%, rgba(74, 86, 142, .34), transparent 66%),
    radial-gradient(800px 480px at 4% 96%, rgba(229, 96, 42, .07), transparent 60%);
}
.hero.hs {
  overflow: clip;
  background: var(--hs-ground), var(--navy-900);
}
/* On large screens the hero fills the first screen, with the facts along its foot */
@media (min-width: 960px) and (min-height: 700px) {
  .hero.hs { display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; }
  .hero.hs > .hs-grid { flex: 1 0 auto; }
}
/* Laptop screens (700-959px tall): a tighter rhythm, so all three facts, their
   descriptions included, sit on the first screen (1024x768 to 1920x900). The
   headline and the stone only ever get smaller here, never larger; the grid above
   is centred in whatever height is left over. */
@media (min-width: 960px) and (min-height: 700px) and (max-height: 959px) {
  .hero.hs { padding-top: calc(var(--header-h) + 3vh); }
  .hero.hs .hs-title { font-size: clamp(2.7rem, min(1.1rem + 4.6vw, 10vh), 5.5rem); }
  .hero.hs .hero-lead { margin-top: 22px; }
  .hero.hs .hero-actions { margin-top: 30px; }
  .hero.hs .hs-stone { max-width: calc((100vh - 300px) / 1.23); max-width: calc((100svh - 300px) / 1.23); }
  .hero.hs .facts { margin-top: 4vh; }
  .hero.hs .fact { padding-block: 20px 24px; }
}
/* styles.css draws the portico lines with .hero::before; here they live in .hs-portico */
.hero.hs::before { content: none; }

.hs-sr {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------ portico */
/* Six hairlines, one for each column of the Courts of Justice portico, spaced
   across the content width. They fade out before the header and before the facts
   (so they never cross its dividers), and the ones near the stone catch the same
   light as the stone. */
.hs-portico {
  --cols: repeating-linear-gradient(to right,
    transparent 0 calc(100% / 12 - .5px),
    #000 calc(100% / 12 - .5px) calc(100% / 12 + .5px),
    transparent calc(100% / 12 + .5px) calc(100% / 6));
  position: absolute; top: 0; bottom: 0; z-index: -1; pointer-events: none;
  left: max(var(--gutter), calc((100% - var(--wrap)) / 2));
  right: max(var(--gutter), calc((100% - var(--wrap)) / 2));
  -webkit-mask-image: linear-gradient(to bottom, transparent 5%, #000 24%, #000 58%, transparent 77%);
  mask-image: linear-gradient(to bottom, transparent 5%, #000 24%, #000 58%, transparent 77%);
}
.hs-portico::before, .hs-portico-lit {
  content: ""; position: absolute; inset: 0;
  -webkit-mask-image: var(--cols); mask-image: var(--cols);
}
.hs-portico::before { background: rgba(255, 255, 255, .042); }
.hs-portico-lit { overflow: hidden; }
.hs-lamp {
  position: absolute; left: 0; top: 0; width: 1000px; height: 1000px; margin: -500px 0 0 -500px;
  background: radial-gradient(closest-side, rgba(244, 232, 206, .3), rgba(244, 232, 206, .1) 45%, rgba(244, 232, 206, 0));
  transform: translate3d(75vw, 30vh, 0);
  opacity: 0; transition: opacity 1.4s ease;
  will-change: transform;
}
.hs-lamp.is-on { opacity: 1; }
@media (min-width: 960px) {
  /* over the text the lines are fainter still, so they never compete with it */
  .hs-portico::before {
    -webkit-mask-image: var(--cols), linear-gradient(to right, rgba(0, 0, 0, .4) 44%, #000 62%);
    mask-image: var(--cols), linear-gradient(to right, rgba(0, 0, 0, .4) 44%, #000 62%);
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
  .hs-portico-lit {
    -webkit-mask-image: var(--cols), linear-gradient(to right, transparent 50%, #000 66%);
    mask-image: var(--cols), linear-gradient(to right, transparent 50%, #000 66%);
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
}

/* ------------------------------------------------------------ eyebrow */
/* On phones the place goes on its own line, rather than a dot dangling at a line end */
@media (max-width: 559px) {
  .hs-eyebrow .hs-sep {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .hs-eyebrow .hs-place { display: block; margin-top: 1px; }
  .hs-eyebrow { align-items: flex-start; }
  .hs-eyebrow::before { margin-top: .36em; }
}
/* Maltese and Italian have a longer place name, which would leave "Malta" alone on
   the second line at these widths: there too the place takes a line of its own */
@media (min-width: 560px) and (max-width: 599px), (min-width: 960px) and (max-width: 1119px) {
  .hs-eyebrow:not(:lang(en)) .hs-sep {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .hs-eyebrow:not(:lang(en)) .hs-place { display: block; margin-top: 1px; }
  .hs-eyebrow:not(:lang(en)) { align-items: flex-start; }
  .hs-eyebrow:not(:lang(en))::before { margin-top: .36em; }
}

/* ------------------------------------------------------------ headline */
.hs-title .hs-art { display: block; }
.hs-title .line { display: block; }

/* The words share one grid cell, so the line is as wide as the widest word and
   nothing moves when the word changes. */
.hs-words { display: inline-grid; white-space: nowrap; vertical-align: baseline; }
.hs-word {
  grid-area: 1 / 1;
  font-style: italic; font-weight: 450; color: var(--orange);
  /* room inside the box for the italic overhang, the ascenders and descenders
     (the masks below only paint inside the box); the margins cancel it */
  padding: .22em .2em .3em .04em; margin: -.22em -.2em -.3em -.04em;
}
.hs-word:not(.is-current):not(.is-out) { visibility: hidden; }
/* hero.js adds the other words as empty elements and they are drawn from
   data-word, so the page's text never runs them together */
.hs-word[data-word]::before { content: attr(data-word); }

/* Maltese and Italian: the article and the possessive change with the noun, so
   the changing part is a whole phrase ("la vostra invenzione") with the line to
   itself. Where the headline is too narrow for the longest phrase on one line
   (phones), every phrase turns onto two lines at its line break (a \n in
   i18n.json), so the four phrases always take the same lines and nothing below
   them moves. Widths are in ems of the headline: the longest Maltese phrase
   ("l-invenzjoni tiegħek") is 7.04em wide, the longest Italian one ("la vostra
   invenzione") 7.14em; the headline is 6.4em wide on a 320px phone, 7em at
   390px, 7.1em at 414px and 7.3em or more from 430px up (7.32em at 960px, the
   narrowest desktop hero). The phrases take one line only where the headline is
   wider than 7.3em, with at least 10px to spare. These widths are EB Garamond's: a wider fallback
   font would not fit, so hero.js changes the phrase only once the italic has
   loaded. Browsers without container queries always use two lines. */
.hs-title--phrase { container-type: inline-size; }
@container (max-width: 7.3em) {
  .hs-words--phrase .hs-word { white-space: pre; }
}
@supports not (container-type: inline-size) {
  .hs-words--phrase .hs-word { white-space: pre; }
}

/* One soft wipe from left to right: a narrow soft edge (about a letter wide)
   erases the old word and the new one is written a moment behind it, so a still
   frame shows at most one dimmed letter, never a gap or two words on top of each
   other. The masks are 2.2 times the word's width, so the edge starts and ends
   fully outside it. */
.js .hs-word.is-in, .js .hs-word.is-out {
  -webkit-mask-size: 220% 100%; mask-size: 220% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.js .hs-word.is-in {
  -webkit-mask-image: linear-gradient(90deg, #000 45.5%, transparent 54.5%);
  mask-image: linear-gradient(90deg, #000 45.5%, transparent 54.5%);
  animation: hs-write .9s cubic-bezier(.5, .05, .25, 1) .06s both;
}
.js .hs-word.is-out {
  -webkit-mask-image: linear-gradient(90deg, transparent 45.5%, #000 54.5%);
  mask-image: linear-gradient(90deg, transparent 45.5%, #000 54.5%);
  animation: hs-sweep .9s cubic-bezier(.5, .05, .25, 1) both;
}
@keyframes hs-write {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; transform: translate3d(0, .06em, 0); }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; transform: none; }
}
@keyframes hs-sweep {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; transform: none; }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; transform: translate3d(0, -.04em, 0); }
}

/* Phones: a bigger headline, so it outweighs the lead */
@media (max-width: 559px) {
  .hs-title { font-size: clamp(2.7rem, .9rem + 9.2vw, 3.3rem); }
}

/* ------------------------------------------------------------ pause */
/* A quiet text control beside the buttons, set like the eyebrow. It is shown
   only while something moves on its own, then fades out (keeping its place).
   With JavaScript its place is kept from the first paint, invisible until hero.js
   has wired it up (.hs-ready), so nothing below it moves when it appears; on phones
   it has a row of its own. Without JavaScript it is not there at all. */
.hs-pause { display: none; }
.js .hs-pause {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; margin-left: 6px; padding: 0 6px 0 2px;
  border: 0; border-radius: 4px; background: none; cursor: pointer;
  font: 600 .72rem/1 var(--sans); letter-spacing: .16em; text-transform: uppercase;
  color: var(--navy-300);
  transition: color .3s ease, opacity .6s ease, visibility 0s linear 0s;
}
.js .hs:not(.hs-ready) .hs-pause { visibility: hidden; }
.hs-pause:hover, .hs-pause:focus-visible { color: #fff; }
.hs-pause-icon {
  position: relative; display: grid; place-items: center; flex: none;
  width: 24px; height: 24px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(200, 205, 226, .42);
  transition: box-shadow .3s ease;
}
.hs-pause:hover .hs-pause-icon, .hs-pause:focus-visible .hs-pause-icon { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .8); }
.hs-pause-icon::before {
  content: ""; width: 7px; height: 9px;
  background: linear-gradient(to right, currentColor 0 2.2px, transparent 2.2px 4.8px, currentColor 4.8px 7px);
}
.hs-pause.is-paused .hs-pause-icon::before {
  width: 8px; margin-left: 2px; background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.js .hs-pause.is-done {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: color .3s ease, opacity .8s ease, visibility 0s linear .8s;
}

/* ------------------------------------------------------------ the stone */
.hs-grid { align-items: center; }
.hs-stone { position: relative; justify-self: end; width: min(100%, 400px); }
.hs-stone-set { position: relative; }
/* The stone fades in from 1% rather than 0. While an element sits at exactly
   opacity 0, WebKit drops its painted layer, and the fade would then re-render the
   four feTurbulence filters (an 80-150 ms stall in Safari). Only the name changes:
   duration, delay, easing and fill still come from [data-hero] in styles.css. */
@keyframes hs-stone-in { from { opacity: .01; transform: translateY(20px); } }
.js:not(.intro-on) .hs-stone { animation-name: hs-stone-in; }

.stone {
  position: relative; width: 100%; aspect-ratio: var(--sw) / var(--sh);
  isolation: isolate; touch-action: pan-y;
  -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent;
}
/* older browsers without aspect-ratio (iOS 14): hold the height open */
@supports not (aspect-ratio: 1) {
  .stone::before { content: ""; display: block; padding-top: calc(var(--sh) / var(--sw) * 100%); }
}
.stone--wide { display: none; }
.stone > svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* separate layers: moving the light repaints only .stone-light */
.stone-base, .stone-light { will-change: transform; }

/* The bed: the stone is set into the navy wall, with a dark joint all round. */
.stone-bed {
  position: absolute; inset: 0; z-index: -2; border-radius: 1px;
  box-shadow: 0 0 0 3px rgba(6, 9, 24, .5), 0 0 18px 3px rgba(6, 9, 24, .32);
}
/* the slab's own shadow inside the joint and on the wall, falling away from the light */
.stone-cast {
  position: absolute; inset: 0; z-index: -1; border-radius: 1px;
  box-shadow: 0 1px 2px rgba(3, 5, 16, .6), 0 18px 36px -16px rgba(3, 5, 16, .8);
  transform: translate3d(3px, 4px, 0);
  will-change: transform;
}

/* Raking shade and a soft glow over the whole slab, chamfers included (so an edge
   in shade is never lighter than the face beside it), moved with transforms only. */
.stone-face { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.stone-shade {
  position: absolute; left: -50%; top: -50%; width: 200%; height: 200%;
  background: linear-gradient(90deg,
    rgba(255, 250, 236, .2) 26%, rgba(255, 250, 236, 0) 43%,
    rgba(58, 42, 28, 0) 49%, rgba(58, 42, 28, .14) 62%, rgba(36, 28, 32, .34) 78%);
  transform: rotate(54deg); opacity: .85;
  will-change: transform, opacity;
}
.stone-glow {
  position: absolute; left: 50%; top: 50%; width: 130%; aspect-ratio: 1; margin: -65% 0 0 -65%;
  background: radial-gradient(closest-side, rgba(255, 251, 240, .9), rgba(255, 248, 232, .34) 42%, rgba(255, 248, 232, 0));
  mix-blend-mode: soft-light;
  transform: translate3d(-32%, -38%, 0); opacity: .6;
  will-change: transform, opacity;
}

/* ------------------------------------------------------------ entrance */
/* The headline is the largest thing on the first screen (the LCP), so it is never
   invisible: it starts at once, part-faded, and settles into place. */
@keyframes hs-rise { from { opacity: .3; transform: translate3d(0, .22em, 0); } }
.js:not(.intro-on) .hs-line { animation: hs-rise 1.1s var(--ease) both; animation-delay: calc(var(--i) * 70ms); }

/* ------------------------------------------------------------ responsive */
/* Big screens: a larger stone, so the two halves stay in balance */
@media (min-width: 1600px) {
  .hs-stone { width: clamp(400px, 24vw, 500px); }
}
@media (max-width: 1099px) {
  .hs-stone { width: min(100%, 360px); }
}
@media (max-width: 959px) {
  .hs-stone { justify-self: stretch; width: 100%; max-width: 520px; }
  .stone--tall { display: none; }
  .stone--wide { display: block; }
  .hs-lamp { width: 640px; height: 640px; margin: -320px 0 0 -320px; }
  .hs-lamp.is-on { opacity: .38; }
  .hs-portico::before { background: rgba(255, 255, 255, .034); }
  /* the lines stay clear of the text and frame the stone only */
  .hs-portico {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent var(--hs-lines-top, 55%), #000 var(--hs-lines-in, 64%), #000 var(--hs-lines-out, 78%), transparent var(--hs-lines-end, 88%));
    mask-image: linear-gradient(to bottom, transparent 0, transparent var(--hs-lines-top, 55%), #000 var(--hs-lines-in, 64%), #000 var(--hs-lines-out, 78%), transparent var(--hs-lines-end, 88%));
  }
}
@media (max-width: 759px) and (prefers-reduced-motion: no-preference) {
  /* the pause control takes its own row under the two buttons, and that row is
     most of the space between the buttons and the stone */
  .js .hs-pause { margin: -6px 0 0 -2px; }
  .js .hs-grid { row-gap: 20px; }
}
@media (max-width: 559px) {
  .hero.hs { padding-top: calc(var(--header-h) + 32px); }
}

@media (prefers-reduced-motion: reduce) {
  .js .hs-word.is-in, .js .hs-word.is-out { animation: none; -webkit-mask-image: none; mask-image: none; }
  .js .hs-pause { display: none; }
}
@media (forced-colors: active) {
  .hs-word { color: CanvasText; }
  .stone-bed, .stone-cast, .stone-face { display: none; }
  .hs-pause-icon { box-shadow: none; border: 1px solid ButtonText; }
}
