/*
  w9w6.com hub. The idea: a circuit board. W9W6 is the chip at the centre, and
  every product is a lit pad at the end of a trace from it. A lit pad is a
  product with its own site (a link); a dim one is still being built. The home
  page talks about the company; each product's own site carries its details
  and its own design.

  The hub is dark in both colour schemes: a lit board needs a dark ground. The
  tokens below override base.css for this site only (hub.css loads after it).

  The chip's glyph pivot is coupled to the markup: the glyph in index.html and
  ar/index.html sits at translate(100 102) scale(1.6), whose visual centre is
  (100, 104) in the 200-unit viewBox. transform-origin on .flip must match, or
  the turn wobbles.
*/

:root {
  color-scheme: dark;
  --ground: #060a12;
  --surface: #0f1826;
  --ink: #e8eef0;
  --ink-2: #a6b4be;
  --rule: #1f2c3b;
  --brand: #8ea4ff;
  --teal: #45cdb9;
  --line-rent: #4fc48c;
  --line-next: #6b7885;
  --warn: #ffc27a;
  --warn-bg: #3a2a12;
}

.mark-tile {
  fill: var(--surface);
  stroke: var(--rule);
  stroke-width: 2;
}

/* ---------- the board ---------- */

/* The board runs up behind the header, so it reaches the top of the page. */
.site-head {
  position: relative;
  z-index: 2;
}
.sky {
  --head: 5rem;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-block-start: calc(-1 * var(--head));
  padding-block: calc(var(--head) + 0.5rem) clamp(2.5rem, 5vw, 4rem);
}

/* Soft edges top and bottom, and a vignette, so the board fades into the page. */
.sky::before,
.sky::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  z-index: 0;
  pointer-events: none;
}
.sky::before {
  inset-block: 0;
  background:
    linear-gradient(var(--ground), transparent 3rem),
    radial-gradient(ellipse 75% 70% at 50% 40%, transparent 45%, rgb(6 10 18 / 0.85));
}
.sky::after {
  inset-block-end: 0;
  block-size: 50%;
  background: linear-gradient(transparent, rgb(6 10 18 / 0.9) 45%, var(--ground) 75%);
}

/*
  The stage. --sw is its width, --k its height over its width. The board image
  is drawn 1.9 x --sw wide and centred on the stage, so the chip in the middle
  of the image sits under the HTML chip (.core).
*/
.circuit {
  --k: 0.58;
  --sw: min(100vw - 2 * var(--gutter), 62rem, max(22rem, (100svh - 20rem) / var(--k)));
  /* No z-index here on purpose: the board (z-index -1) must sit under the
     section's fades, and the traces and pads (.signals) above them. */
  position: relative;
  inline-size: var(--sw);
  aspect-ratio: 1 / var(--k);
  margin-inline: auto;
}

/* Physical left/top throughout the board: it is a picture and does not mirror
   in Arabic. A right-to-left static position would throw it off screen. */
.board {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: -1;
  inline-size: 0;
  block-size: 0;
  pointer-events: none;
}
.board img {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  max-width: none;
  inline-size: calc(var(--sw) * 1.9);
  block-size: auto;
}
.pcb {
  translate: -50% -50%;
  opacity: 0.75;
}

/*
  The scan: a band of light that crosses the board. The band moves one way and
  the lit copy of the board inside it moves the other way by the same amount,
  so the lit traces stay in register with the dim ones underneath. Two
  transforms, nothing repainted. At rest the band waits off the left edge.
*/
.scan {
  position: absolute;
  top: calc(var(--sw) * -0.59375);
  left: calc(var(--sw) * -0.95);
  inline-size: calc(var(--sw) * 0.45);
  block-size: calc(var(--sw) * 1.1875);
  overflow: hidden;
  transform: translateX(calc(var(--sw) * -0.45));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 45%, #000 55%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 45%, #000 55%, transparent);
}
.board .pcb-lit {
  transform: translateX(calc(var(--sw) * 0.45));
}

/* ---------- the chip ---------- */

.core {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  inline-size: clamp(4.75rem, 13%, 8rem);
  translate: -50% -50%;
}
.core::before {
  content: "";
  position: absolute;
  inset: -45%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(46 230 200 / 0.22), rgb(108 140 255 / 0.08) 60%, transparent);
}
.core svg {
  display: block;
  inline-size: 100%;
  block-size: auto;
  overflow: visible;
}
.pins {
  fill: none;
  stroke: #9db0ff;
  stroke-opacity: 0.6;
  stroke-width: 5;
}
.package {
  fill: #0a111d;
  stroke: #9db0ff;
  stroke-opacity: 0.55;
  stroke-width: 2.5;
}
.die {
  fill: none;
  stroke: #2ee6c8;
  stroke-opacity: 0.25;
  stroke-width: 1.5;
}
.flip {
  fill: none;
  stroke: url(#mark-stroke);
  stroke-width: 5;
  stroke-linecap: round;
  transform-origin: 100px 104px;
}
/* The pin-1 dot: it marks which way up the chip is, so it turns with the digit. */
.sat {
  fill: #2ee6c8;
  transform-origin: 100px 100px;
}

/* ---------- signals: a trace from the chip, a pad at its end ---------- */

/*
  Each signal fills the stage. A trace leaves the chip at (--sx, --sy) and runs
  in two straight legs to its pad at (--x, --y), in percent of the stage:
  .hv goes across first, then up or down; .vh goes up or down first, then
  across. --hd and --vd are the directions (1 right or down, -1 left or up);
  each leg is drawn from its start and flipped by them.
*/
.signals,
.signal {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.signals {
  z-index: 1;
}
.s-rent { --sx: 54; --sy: 50; --x: 73; --y: 25; --hd: 1; --vd: -1; --c: var(--line-rent); }
.f1 { --sx: 50; --sy: 54; --x: 21; --y: 28; --hd: -1; --vd: -1; --c: #9db0ff; }
.f2 { --sx: 50; --sy: 54; --x: 84; --y: 66; --hd: 1; --vd: 1; --c: #9db0ff; }
.f3 { --sx: 46; --sy: 50; --x: 41; --y: 10; --hd: -1; --vd: -1; --c: #9fe9dc; }

.seg {
  position: absolute;
  overflow: hidden;
  --w: 3px;
}
.forming .seg {
  --w: 2px;
}
/* Across legs. */
.hv .seg-a,
.vh .seg-b {
  width: calc((var(--x) - var(--sx)) * var(--hd) * 1%);
  height: var(--w);
  margin-top: calc(var(--w) / -2);
  transform-origin: 0 50%;
  scale: var(--hd) 1;
  background: color-mix(in srgb, var(--c) 60%, transparent);
}
.hv .seg-a {
  left: calc(var(--sx) * 1%);
  top: calc(var(--sy) * 1%);
}
.vh .seg-b {
  left: calc(var(--sx) * 1%);
  top: calc(var(--y) * 1%);
}
/* Up-and-down legs. */
.hv .seg-b,
.vh .seg-a {
  width: var(--w);
  height: calc((var(--y) - var(--sy)) * var(--vd) * 1%);
  margin-left: calc(var(--w) / -2);
  transform-origin: 50% 0;
  scale: 1 var(--vd);
  background: color-mix(in srgb, var(--c) 60%, transparent);
}
.hv .seg-b {
  left: calc(var(--x) * 1%);
  top: calc(var(--sy) * 1%);
}
.vh .seg-a {
  left: calc(var(--sx) * 1%);
  top: calc(var(--sy) * 1%);
}
.forming.hv .seg-a,
.forming.vh .seg-b {
  background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--c) 35%, transparent) 0 6px, transparent 6px 11px);
}
.forming.hv .seg-b,
.forming.vh .seg-a {
  background: repeating-linear-gradient(180deg, color-mix(in srgb, var(--c) 35%, transparent) 0 6px, transparent 6px 11px);
}

/* The data: a bright streak that runs along each leg in turn, chip to pad. */
.seg::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
}
.hv .seg-a::after,
.vh .seg-b::after {
  background: linear-gradient(90deg, transparent 60%, #fff 92%, transparent);
}
.hv .seg-b::after,
.vh .seg-a::after {
  background: linear-gradient(180deg, transparent 60%, #fff 92%, transparent);
}

.spark {
  position: absolute;
  left: calc(var(--x) * 1%);
  top: calc(var(--y) * 1%);
  display: grid;
  justify-items: center;
  gap: 0.35rem;
  translate: -50% -0.6rem;
  pointer-events: auto;
}
.pad {
  position: relative;
  display: block;
  inline-size: 1.2rem;
  block-size: 1.2rem;
}
.pad::before,
.pad::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  border-radius: 0.2rem;
}
.pad::before {
  inline-size: 0.85rem;
  block-size: 0.85rem;
  background: var(--c);
  box-shadow:
    0 0 0.5rem 0.1rem var(--c),
    0 0 1.6rem 0.4rem color-mix(in srgb, var(--c) 40%, transparent);
}
/* The ring that keeps leaving the pad. */
.pad::after {
  border: 2px solid var(--c);
  opacity: 0;
}
.forming .pad::before {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  opacity: 0.6;
  box-shadow: 0 0 0.6rem 0.1rem color-mix(in srgb, var(--c) 50%, transparent);
}

a.spark {
  padding: 0 0.5rem 0.4rem;
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--radius);
}
.label {
  display: grid;
  justify-items: center;
  padding: 0.3rem 0.75rem 0.35rem;
  border: 1px solid color-mix(in srgb, var(--c) 35%, transparent);
  border-radius: var(--radius);
  background: rgb(6 10 18 / 0.85);
  line-height: 1.35;
  white-space: nowrap;
}
.name {
  font-family: var(--font-display);
  font-weight: 600;
}
.addr {
  color: var(--ink-2);
  font-size: var(--step--1);
  direction: ltr;
  unicode-bidi: isolate;
}
a.spark .pad::before {
  transition: transform 0.3s var(--ease-out);
}
a.spark:hover .pad::before,
a.spark:focus-visible .pad::before {
  transform: scale(1.35);
}
a.spark:hover .name {
  text-decoration: underline;
  text-decoration-color: var(--c);
  text-underline-offset: 0.25em;
}

/* ---------- intro ---------- */

.intro {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  align-items: end;
  gap: 1.25rem clamp(2rem, 5vw, 5rem);
  margin-block-start: clamp(0.5rem, 2vw, 1.5rem);
}
.intro h1 {
  font-size: var(--step-4);
  max-inline-size: 17ch;
}
:lang(ar) .intro h1 {
  max-inline-size: 15ch;
}
.lead {
  max-inline-size: 34rem;
  color: var(--ink-2);
  font-size: var(--step-1);
}

/* ---------- the idea behind the name ---------- */

.idea {
  border-block-start: 1px solid var(--rule);
}
.idea-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.25rem clamp(2rem, 5vw, 5rem);
  align-items: start;
  margin-block-end: clamp(2.5rem, 5vw, 4rem);
}
.idea-head h2 {
  font-size: var(--step-3);
  max-inline-size: 16ch;
}
.idea-head p {
  color: var(--ink-2);
  font-size: var(--step-1);
  max-inline-size: 36rem;
}

.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 2.25rem clamp(1.5rem, 3vw, 2.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
.principles li {
  padding-block-start: 1rem;
  border-block-start: 3px solid var(--brand);
}
.principles li:nth-child(2) {
  border-color: var(--teal);
}
.principles li:nth-child(3) {
  border-color: var(--line-rent);
}
.principles li:nth-child(4) {
  border-color: #9fe9dc;
}
.principles h3 {
  font-size: var(--step-2);
  margin-block-end: 0.5rem;
}
.principles p {
  color: var(--ink-2);
  max-inline-size: 30ch;
}

.site-foot {
  border-color: var(--rule);
}

/* ---------- narrow screens ---------- */

@media (max-width: 47.99rem) {
  .circuit {
    --k: 0.86;
    --sw: min(100vw - 2 * var(--gutter), 34rem);
  }
  .f1 { --x: 14; --y: 30; }
  .f2 { --x: 88; --y: 70; }
  .f3 { --x: 38; --y: 8; }
  .s-rent { --x: 76; --y: 16; }
  .intro,
  .idea-head {
    grid-template-columns: 1fr;
  }
}

/* ---------- motion ----------
   One load sequence, then a board that keeps working:
   - the board fades up, and the 9 on the chip turns and lands as the 6, and
     keeps turning: 9, then 6, then 9 again, every nine seconds;
   - traces draw out from the chip, pads light at their ends;
   - then, for as long as the page is open, data runs along each trace, a ring
     leaves each pad, and a scan of light crosses the board every nine seconds.
   Transform and opacity only. */

@media (prefers-reduced-motion: no-preference) {
  .board {
    animation: rise 1.6s var(--ease-out) both;
  }
  /* 9 -> 6 -> 9, forever: one half-turn every 4.5 s. The negative delay starts
     the cycle just before its first turn, so the 9 turns into the 6 at 0.45 s. */
  .flip,
  .sat {
    animation: nine-six 9s -2.7s infinite;
  }
  .scan {
    will-change: transform;
    animation: scan-band 9s ease-in-out 1.2s infinite;
  }
  .board .pcb-lit {
    will-change: transform;
    animation: scan-copy 9s ease-in-out 1.2s infinite;
  }
  .seg-a {
    animation: draw 0.5s var(--ease-in, ease-in) var(--t, 1.3s) both;
  }
  .seg-b {
    animation: draw 0.5s var(--ease-out) calc(var(--t, 1.3s) + 0.5s) both;
  }
  .spark {
    animation: light 0.6s var(--ease-out) calc(var(--t, 1.3s) + 0.9s) both;
  }
  .seg-a::after {
    animation: data-a 3s linear calc(var(--t, 1.3s) + 1.4s) infinite;
  }
  .seg-b::after {
    animation: data-b 3s linear calc(var(--t, 1.3s) + 1.4s) infinite;
  }
  .hv .seg-a::after,
  .vh .seg-b::after {
    --from: translateX(-100%);
  }
  .hv .seg-b::after,
  .vh .seg-a::after {
    --from: translateY(-100%);
  }
  .pad::after {
    animation: ring 3s var(--ease-out) calc(var(--t, 1.3s) + 2.1s) infinite;
  }
  .forming .seg::after,
  .forming .pad::after {
    animation-duration: 6s;
  }
  .s-rent { --t: 1.2s; }
  .f1 { --t: 1.45s; }
  .f2 { --t: 1.65s; }
  .f3 { --t: 1.85s; }
}

/* Reduced motion keeps the story as a sequence, not travel: the board fades up,
   the 9 and the 6 trade places by fading, and the pads fade in on their traces.
   Only the digit swap repeats; nothing moves across the screen. */
@media (prefers-reduced-motion: reduce) {
  .board {
    animation: fade 1.2s ease both;
  }
  .flip,
  .sat {
    animation: nine-six-swap 9s -2.7s infinite;
  }
  .core {
    animation: fade 0.9s ease 0.3s both;
  }
  .signals {
    animation: fade 0.9s ease 1s both;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes nine-six {
  0%,
  35% {
    transform: rotate(0deg);
    animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  }
  50%,
  85% {
    transform: rotate(180deg);
    animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  }
  100% {
    transform: rotate(360deg);
  }
}
@keyframes nine-six-swap {
  0%,
  38% {
    opacity: 1;
    transform: rotate(0deg);
  }
  42.4% {
    opacity: 0;
    transform: rotate(0deg);
  }
  42.5% {
    opacity: 0;
    transform: rotate(180deg);
  }
  47%,
  88% {
    opacity: 1;
    transform: rotate(180deg);
  }
  92.4% {
    opacity: 0;
    transform: rotate(180deg);
  }
  92.5% {
    opacity: 0;
    transform: rotate(360deg);
  }
  97%,
  100% {
    opacity: 1;
    transform: rotate(360deg);
  }
}
/* The band crosses the board in the first 55% of the cycle, then rests off the
   right edge and jumps back unseen. */
@keyframes scan-band {
  0% {
    transform: translateX(calc(var(--sw) * -0.45));
  }
  55%,
  100% {
    transform: translateX(calc(var(--sw) * 1.9));
  }
}
@keyframes scan-copy {
  0% {
    transform: translateX(calc(var(--sw) * 0.45));
  }
  55%,
  100% {
    transform: translateX(calc(var(--sw) * -1.9));
  }
}
@keyframes draw {
  from {
    transform: scale(0, 0);
  }
  to {
    transform: none;
  }
}
@keyframes light {
  from {
    opacity: 0;
    transform: scale(0.4);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* Leg a carries the data for the first 40% of the cycle, leg b the next 40%. */
@keyframes data-a {
  0% {
    opacity: 1;
    transform: var(--from);
  }
  40% {
    opacity: 1;
    transform: none;
  }
  40.1%,
  100% {
    opacity: 0;
    transform: none;
  }
}
@keyframes data-b {
  0%,
  40% {
    opacity: 0;
    transform: var(--from);
  }
  40.1% {
    opacity: 1;
    transform: var(--from);
  }
  80% {
    opacity: 1;
    transform: none;
  }
  80.1%,
  100% {
    opacity: 0;
    transform: none;
  }
}
@keyframes ring {
  0% {
    opacity: 0.8;
    transform: scale(0.6);
  }
  100% {
    opacity: 0;
    transform: scale(3);
  }
}
@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
