/* Page backdrop: faint grid, accent bloom, oversized brand watermarks.
 *
 * This used to live inside backtotop.js and get injected at runtime, which meant
 * the whole backdrop could not paint until the script had downloaded and run.
 * On a page it showed up as: text first, then grid, then logos, arriving in
 * three visible steps. As a stylesheet in <head> it is render-blocking, so it
 * paints in the same frame as the content.
 *
 * Uses var(--accent), so it turns orange by itself on TB pages.
 */

.stage { position: relative; }

/* ⚠️ THE MARKS HANG PAST THE VIEWPORT ON PURPOSE (#bgart right:-120px, #bgart2 left:-90px), and
 * once the drift animation puts a transform on them Chrome counts them as scrollable width - a
 * phone could pan ~30px sideways into empty space. index.html already carried this guard for its
 * #sky; every page loading this file gets it now. `clip`, not `hidden`: hidden would turn the
 * root into a scroll container and break position:sticky bars. */
html { overflow-x: clip; }

/* Keep the centred top-bar logo at the TRUE viewport centre on every page.
 * The marketing pages scroll the <body>, so a page tall enough to need a
 * scrollbar loses ~10px of width on the right, which shifted the `1fr auto 1fr`
 * logo ~5px left versus a short page (and versus the app home, which scrolls an
 * inner pane and never loses header width). `stable both-edges` reserves a
 * matching gutter on the opposite side, so the content box stays symmetric and
 * the logo lands dead centre whether or not a scrollbar is present.
 * Scoped off the app (`.stage.app` = home / workspace) so the tool itself, which
 * already centres correctly and sits flush to the edge, gets no side gutters.
 * UPDATE: `both-edges` reserved a matching strip on the LEFT too, which reads as
 * an empty gap on any page with a full-bleed background. Plain `stable` reserves
 * the gutter only where the scrollbar actually is, and reserves it ALWAYS (even
 * on short pages), so the width stays constant page to page and the logo still
 * never shifts. Same fix, no gap. */
/* scrollbar-gutter removed: reserving a gutter left a visible bare strip beside
   the stage background (left edge with both-edges, right edge with stable).
   Not worth it for a ~7px logo shift on short pages. */

/* ---- one scrollbar for the whole site ----
   Every page used to set its own near-black track (#0a0e18), which reads as a
   hard black bar against the lighter footer. Transparent track + a soft rounded
   thumb blends everywhere and warms to the accent on hover. This file loads
   after each page's own <style>, so it overrides them all from one place. */
/* Matched to the app (arthur-ui-v2 uses --line2 #343d4a on a transparent track). White at 20%
   sat noticeably brighter than the page and read as a light bar down the side; the app looks
   like part of the page and the site did not. */
html { scrollbar-color: #343d4a transparent; scrollbar-width: thin; }
/* The same faint grid on <html> as on .stage::before below, so it CONTINUES under the
   scrollbar gutter. .stage is only as wide as the content box, so the ~10px the scrollbar
   occupies fell outside it and showed flat page colour: a plain strip down the right with
   no grid lines in it. background-attachment:fixed anchors this to the viewport exactly
   like the fixed pseudo-element, so the two line up cell for cell. */
html {
  background-image:
    linear-gradient(rgba(255,255,255,.075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.075) 1px, transparent 1px);
  background-size: 52px 52px;
  background-attachment: fixed;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #343d4a;
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(59,130,246,.62);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:active { background: rgba(59,130,246,.85); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* Faint grid, fixed and non-interactive.
   The mask used to reach transparent at 90%, which killed the grid entirely
   across the bottom of the screen and left the lower half looking bare. It now
   bottoms out at 22% instead of 0, so the grid thins but never vanishes. */
.stage::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.075) 1px, transparent 1px);
  background-size: 52px 52px;
  -webkit-mask-image: radial-gradient(1600px 1500px at 50% 4%, #000 0%, rgba(0,0,0,.62) 58%, rgba(0,0,0,.22) 100%);
  mask-image: radial-gradient(1600px 1500px at 50% 4%, #000 0%, rgba(0,0,0,.62) 58%, rgba(0,0,0,.22) 100%);
}

/* Soft accent bloom.
   inset:-220px, NOT 0. This layer is animated sideways; at exactly viewport size
   its own edge slides into view and slices the gradient off mid-fade, which
   showed up as a hard vertical line down the screen. Oversizing it keeps every
   edge well outside the viewport for the whole travel. */
.stage::after {
  content: ""; position: fixed; inset: -220px; pointer-events: none; z-index: 0; opacity: .20;
  background:
    radial-gradient(760px 680px at 86% 4%, var(--accent), transparent 62%),
    radial-gradient(620px 580px at 8% 88%, var(--accent), transparent 62%),
    /* a third, wider and dimmer pool through the middle so the centre of the
       screen is not dead space between two corner glows */
    radial-gradient(1100px 900px at 50% 50%, var(--accent), transparent 70%);
}

/* Vignette. Sits above the glow and below the content, and darkens the outer
   frame so the middle of the screen reads as lit rather than as empty space.
   Uses body::after because .stage's own ::before and ::after are already the
   grid and the glow, and this needs no extra markup on 19 pages. */
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(125% 90% at 50% 42%, transparent 48%, rgba(0, 0, 0, .55) 100%);
}
/* Much lighter on a light ground: the same 55% black would look like grime. */
body:has(.stage[data-mode="light"])::after {
  background: radial-gradient(125% 90% at 50% 42%, transparent 52%, rgba(18, 26, 42, .16) 100%);
}

/* ===================== LIGHT MODE =====================
   The grid, the watermark and the wordmark are all WHITE, so on a light ground
   they vanish. Swap them to dark ink. Only the app toggles data-mode; the
   marketing pages stay dark, so this never touches them. */
.stage[data-mode="light"]::before {
  background-image:
    linear-gradient(rgba(28, 42, 72, .055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(28, 42, 72, .055) 1px, transparent 1px);
}
.stage[data-mode="light"] #bgart,
.stage[data-mode="light"] #bgart2,
.stage[data-mode="light"] .overlay.fs .fsart,
.stage[data-mode="light"] .overlay.fs .fsart2 { background-image: url(arthur-a-dark.png); }
/* the black-letter wordmark (blue A kept) replaces the white one wherever it is
   used, in one rule, by matching the src */
.stage[data-mode="light"] img[src="arthur-word.png"] { content: url(arthur-word-light.png); }

/* ===================== BATTERY SAVER =====================
   Settings > Background motion = Off sets html[data-motion="off"]. Drop the
   drifting brand marks and stop every backdrop animation. The grid and the
   static glow cost nothing to keep, so they stay. */
html[data-motion="off"] #bgart,
html[data-motion="off"] #bgart2,
html[data-motion="off"] .overlay.fs .fsart,
html[data-motion="off"] .overlay.fs .fsart2 { display: none; }
html[data-motion="off"] .stage::after { animation: none; }

/* oversized brand mark as background art, bottom right */
#bgart {
  position: fixed; right: -120px; bottom: -140px; width: 560px; height: 560px;
  pointer-events: none; z-index: 0; opacity: .055;
  background: url(arthur-a-lg.png) no-repeat center/contain;
}
/* TB swaps the image and nothing else: same box, same position, same drift as the
   Arthur mark, because Panos wants the TB pages to carry a watermark of exactly the
   same weight as every other page. tb-icon.png is only 311px against the Arthur A's
   1024px, so it is upscaled ~1.8x here; a 1px blur takes the hard edge off that
   without shrinking the mark. */
/* ★ 2026-08-16: tb-icon.png is 311px in a 340px box on a phone and 560px on a desktop,
   so its hard edges survive a 1px blur and the mark reads as a tilted panel parked
   mid-screen - Panos called the page chaotic and this is most of why. Blurred properly
   and dimmed, it goes back to being texture instead of an object. */
/* ★ 2026-08-17: 18px was an over-correction - at .05 opacity it erased the mark, and
   Panos noticed the TB pages had no watermark at all while Arthur's do. Arthur's sits in
   the same 340px box at the same .05 with no blur. The blur is only here to take the hard
   edge off a 311px badge that gets upscaled; 4px does that without deleting it. */
/* ★ 2026-08-17 - THE ORANGE COPY. tb-icon.png averages rgb(242,244,247), near white, and a
   white mark over navy reads as cold grey. On the Arthur pages that is fine - the light there
   is blue and grey sits beside it. On TB the light is warm, and a cold mark on a warm ground
   is exactly the "greyish" Panos is seeing. tb-icon-orange.png is the same artwork in
   rgb(255,87,5). Darker ink than white, so it needs more opacity to read at the same weight. */
/* ★ 2026-08-17: back to the white mark. It read as grey only because a cold mark sat on a
   cold blue-black ground while the light was warm - three things disagreeing. With the TB
   palette warmed, white reads as white, and Panos preferred it: "we had them white before,
   it was way better." */
/* The only difference for TB: which mark it is. Same box, same opacity, same drift as
   Arthur's. A 2px blur only because tb-icon.png is 311px and gets upscaled here, where the
   Arthur A is 1024px and needs none. */
.stage.tb #bgart { background-image: url(tb-icon.png); filter: blur(2px); }
/* a second, smaller mark top left for balance */
#bgart2 {
  position: fixed; left: -90px; top: -60px; width: 320px; height: 320px;
  pointer-events: none; z-index: 0; opacity: .035;
  background: url(arthur-a-lg.png) no-repeat center/contain;
  transform: rotate(-14deg);
}
.stage.tb #bgart2 { background-image: url(tb-icon.png); filter: blur(2px); }

/* One shared backdrop everywhere: the app pages (home / workspace) show the SAME
   #bgart marks as the marketing pages, so moving between surfaces only swaps the
   content, never the background. */

/* ===================== AMBIENT MOTION =====================
   The backdrop drifts. Slowly enough that you never catch it moving, only
   notice the page is not a still image.
     - Only `transform` and `opacity` are animated, so the compositor handles it
       and nothing ever reflows.
     - The two marks run on 53s and 71s. Deliberately not multiples of each
       other, so the pair never falls into a visible repeating pattern.
     - The GRID stays perfectly still. A moving grid reads as cheap and makes
       some people queasy; it is the fixed reference the drift is measured
       against, so it has to stay put.
     - the app shares this exact motion now, so nothing jumps when you move
       between the home page, a workspace and the marketing pages. */

/* Amplitudes and speeds are what make this visible at all. The first attempt
   drifted 26px over 53s — under 1px per second, on a shape at 5% opacity, which
   is below the threshold of perception. These travel ~90px in 15s (about 6px/s)
   AND pulse in opacity, because at this contrast a brightness change registers
   far more than a positional one. */
/* 4-point orbits so the marks WANDER around the space (his call) rather than
   sliding to one spot and back. ~110px of travel, in the corners where there is
   room for it. */
/* 2026-07-26 — opacity FLOOR raised.
   These marks are positioned by a NEGATIVE wall-clock delay, so every page load
   starts at a random point in the 24s / 33s cycle. The old ranges (.05–.11 and
   .032–.078) meant a refresh landing near the trough rendered them essentially
   invisible against the near-black page, while one landing near the peak showed
   them clearly — which read as "sometimes the icons load, sometimes they don't".
   They were always loaded; only the phase differed. The pulse is kept (same shape,
   same timing) but now swings between "clearly there" and "a little brighter". */
/* ★★ 2026-08-19 - THE OPACITY CYCLING IS GONE, AND IT WAS THE "FADING" ALL ALONG.
   These keyframes pulsed the marks between .085 and .125 (A, every 24s) and .06 and .092
   (B, every 33s). That is a mark visibly brightening and dimming forever, on every page,
   and it has been in this file far longer than tonight.
   Panos has reported it perhaps six times in different words - "the icon appears and
   disappears", "it fades", "it's still fading, I don't want it to fade" - and every time I
   went looking at stacking, at the footer, at my own proximity fade. The call was coming
   from inside the animation.
   The MOVEMENT stays: he asked twice for the marks to drift and was right that a still
   backdrop looks dead. Only the opacity leaves the keyframes, so the marks now hold one
   steady ink and simply move. */
@keyframes bgDriftA {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  25%      { transform: translate3d(-104px, -70px, 0) rotate(-9deg); }
  50%      { transform: translate3d(-44px, -118px, 0) rotate(5deg); }
  75%      { transform: translate3d(-112px, -22px, 0) rotate(-13deg); }
}
@keyframes bgDriftB {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-14deg); }
  25%      { transform: translate3d(92px, 64px, 0) rotate(-6deg); }
  50%      { transform: translate3d(40px, 112px, 0) rotate(-20deg); }
  75%      { transform: translate3d(104px, 26px, 0) rotate(-9deg); }
}
/* TB used to have its own bgDriftBtb pair (different base angle, dimmer pulse). It
   is gone: he wants the TB marks moving exactly like the Arthur ones, so both
   surfaces now share bgDriftA / bgDriftB. */
/* ★ Same for the light: it was breathing between .15 and .34, which is a 2.3x swing in
   brightness on a loop. That is the other half of "there's weird things going on with the
   lighting" - it genuinely was changing while he looked at it. It holds .20 now, the value
   .stage::after already declares, and only moves. */
@keyframes bgBloom {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(54px, -40px, 0); }
}
/* animation-delay is driven by backtotop.js from the wall clock (--wm-*), so the
   drift is continuous across page loads instead of restarting each navigation. */
.stage #bgart  { animation: bgDriftA 24s ease-in-out infinite; animation-delay: var(--wm-a, 0s); }
.stage #bgart2 { animation: bgDriftB 33s ease-in-out infinite; animation-delay: var(--wm-b, 0s); }
.stage::after  { animation: bgBloom 23s ease-in-out infinite; animation-delay: var(--wm-bloom, 0s); }
/* 2026-07-26: the drift is BACK ON. It was switched off on 07-25 while hunting a
   stutter, but the real cause turned out to be screens fetching their data on click
   and background polls redrawing mid-animation — nothing to do with the backdrop.
   These layers only animate transform/opacity, so the compositor handles them. */

/* ★★ 2026-08-13 - "MY FRIEND'S BACKGROUND WASN'T MOVING."
   This block was the reason, and it was a one-way door. Android's BATTERY SAVER switches on the
   system "remove animations" flag, and Chrome reports that to the page as
   `prefers-reduced-motion: reduce` - so by evening, when half the phones in a restaurant have
   dropped into battery saver, Arthur quietly froze its own backdrop. Nothing was broken, and
   nothing in the app could bring it back: Settings > Background motion could only turn motion
   OFF, never force it ON, because this rule outranked the switch with `!important`.
   ★ AN EXPLICIT CHOICE BEATS AN OS HINT. A phone whose owner has never been asked still gets
   the accessible default (frozen) - people who set Reduce Motion for vestibular reasons must
   keep it. But `data-motion="on"` means the user said so, and it wins. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="on"]) #bgart,
  html:not([data-motion="on"]) #bgart2,
  html:not([data-motion="on"]) .stage::after { animation: none !important; }
}

/* Keep real content above the backdrop.
   .abar is NOT in this list: it is position:sticky in the pages, and setting
   position:relative here silently un-stuck every marketing top bar so they
   scrolled away. It already carries z-index:10 of its own, which is well clear
   of the backdrop, so it needs nothing from us. */
.awrap, .hfoot, .hbar, .shell { position: relative; z-index: 1; }

@media (max-width: 640px) {
  /* .stage.tb is repeated on each selector because `.stage.tb #bgart` outscores a
     bare `#bgart`; without it the TB pages kept the desktop size on a phone. */
  #bgart, .stage.tb #bgart { width: 340px; height: 340px; right: -90px; bottom: -90px; }
  #bgart2, .stage.tb #bgart2 { display: none; }
  /* ⚠️⚠️ THIS WAS THE "WEIRD BLUE THING" ON A PHONE (Panos, 2026-08-11). Pinning the layer to a
     420x420 box while it still carried gradients up to 1100px wide meant the gradients were
     CLIPPED BY THE BOX, so the bloom ended in a hard vertical line and a hard horizontal line
     across the top-left of the screen. It read as a misplaced blue rectangle, not as light.
     The comment at the top of this rule already warned about exactly this ("at exactly viewport
     size its own edge slides into view and slices the gradient off mid-fade") — the desktop rule
     was fixed and the phone override reintroduced it.
     Now: the box stays oversized so every edge is off-screen, and the GRADIENTS are scaled down
     to phone size instead, which is what the shrink was actually for. */
  /* ★★ 2026-08-17 - THE PHONE WAS FLOODED, AND IT WAS A SCALE PROBLEM, NOT A COLOUR ONE.
     On a 1440px desktop the three pools are 760/620/1100px wide: 53%, 43% and 76% of the screen.
     They read as pools of light with dark between them, which is why Panos says the desktop looks
     right. The phone override shrank them to 420/360/620px - but against a 375px viewport that is
     112%, 96% and 165%. Every glow was WIDER THAN THE SCREEN, so instead of pools you got the
     whole viewport washed at close to peak intensity. "It just feels there's so much orange."
     Fixed by sizing them in vw, so the proportion is identical to the desktop at any width and
     the dark space between the pools survives on a phone. */
  .stage::after {
    inset: -160px; width: auto; height: auto; top: -160px; right: -160px; opacity: .17;
    background:
      radial-gradient(53vw 47vw at 86% 4%, var(--accent), transparent 62%),
      radial-gradient(43vw 40vw at 8% 88%, var(--accent), transparent 62%),
      radial-gradient(76vw 62vw at 50% 50%, var(--accent), transparent 70%);
  }
  /* ★★ 2026-08-16 - AND TB NEEDS ITS OWN, OR THE PHONE UNDOES THE FIX ABOVE.
     The rule directly above has no .stage.tb variant, so below 640px every TB page fell back to
     it and got var(--accent) - full-saturation #ff5705 - straight back. The pale-amber fix was
     only ever running on desktop, which is why "the background looks weird" survived it. This is
     the same trap the #bgart comment at the top of this block warns about: on these pages a
     shared selector has to be repeated with .stage.tb or the page-specific version loses.
     The corner placement is dropped too. Two pools at 86%/8% inside a 375px viewport are not
     corner light, they are one half of the screen lit and the other half not, which is the
     lopsided smear down the left. Centred and symmetric, there is no side to notice. */
  /* ★ 2026-08-17: rgba(255,197,142) is nearly white and said nothing - it cured the mud by
     removing the orange, and the TB pages stopped looking like TB. Neither extreme was right:
     raw #ff5705 muds against this navy, near-white has no identity. A mid orange is still
     clearly orange and still reads as light. */
  /* ★★ 2026-08-16 - AND THE BACKGROUND HOLDS STILL ON A PHONE.
     The watermark drifts up to 112px and rotates ±13 degrees while the bloom translates 54px and
     pulses its opacity from .08 to .17, both on ~25 second loops. On a desktop that is ambience
     you never consciously notice. On a phone the whole thing is happening a few inches from your
     face, directly behind the text, and it is a large part of what reads as "weird" and
     "chaotic" - especially for a reader with dyslexia, where movement behind type costs real
     effort. The layers stay, at a fixed point in their cycle; they just stop moving.
     ⚠️ Setting opacity on the rules above does nothing while these run - the keyframes own it,
     which is why it has to be pinned HERE. */
  /* ⚠️ 2026-08-16 stopped all of this on a phone, on my own theory that motion behind text was
     part of what felt chaotic. Panos has asked for the drift back twice since - "the icons are
     still not moving". It is his site and his eye, so it moves again. The prefers-reduced-motion
     block earlier in this file still stops it for anyone whose system asks for that, which is the
     check that actually matters.
     Only the marks' opacity stays pinned, because the drift keyframes animate opacity too and
     the orange ink needs to sit higher than the white one did. */
  #bgart { opacity: .05 !important; }
}


/* ---- 2026-07-27 fixes from Panos's review -------------------------------
   The site's top bar is `1fr auto 1fr`. The Greek labels are far longer than the
   English ones, so the right-hand nav grew into the centred wordmark and clipped
   it to "Arthı". Below 1150px the middle links step aside; back arrow, wordmark
   and the CTA are what matter.

   The TB marks used to be shrunk here (300/210px, blur 2px) on the theory that the
   311px monogram would read as a grey box at full size. Panos looked at it and said
   the opposite: too small, make them the same as the Arthur ones. Removed — the
   sizing now lives in one place, with #bgart / #bgart2 above. */
/* TB pages are orange: the Arthur wordmark in their top bar follows */
.stage.tb .abrand img { content: url(arthur-word-orange.png); }
.abar { gap: 10px; }
.abar .abrand { min-width: 0; }
.abar .abrand img { max-width: 100%; }
@media (max-width: 1150px) { .abar .anav { display: none; } }


/* ============================================================================
   GRID OFF — Panos, 2026-08-03. He never liked the lines: "they didn't match
   with the icons, they didn't match with the stars". The starfield and the
   accent bloom carry the background on their own now.
   The original rules are untouched above; this block simply switches them off.
   ★ TO RESTORE THE GRID EVERYWHERE: delete this block. Nothing else to undo.
   ============================================================================ */
html { background-image: none !important; }
.stage::before { background-image: none !important; }

/* ⚠️ 2026-08-19 - THE SCROLL PARALLAX IS GONE. His words: "make the lighting a part of
   the background. The lighting is literally a part of the scroll, I'm scrolling and the light
   is moving."
   It was added on 8-17 because he said the opposite - "I scroll and the background just stays
   there" - and it was the right read of that complaint at the time. But shifting a gradient's
   background-position is what tore the tile edge across the screen, and even capped at 160px it
   keeps the light tied to the scrollbar instead of to the page. A fixed backdrop that simply
   sits there is what "part of the background" means, and it is the version that cannot break.
   Nothing replaces it - the rule is deleted, so the layers use their natural centre. */


/* ★★ 2026-08-17 - ONE HEADLINE SCALE FOR EVERY PAGE.
   Panos: "I want them all to have the same layout, the same gaps at the top, the same gaps
   at the bottom." Measured across 17 pages there were five different wrap paddings on a
   desktop, five MORE in the phone overrides, and five headline sizes. Nobody chose that; it
   accumulated a page at a time.
   The pages with a .Xhero h1 rule carry the same clamp inline; the twelve without one - the
   legal set, careers, the two about pages - had no size at all and fell back to the browser
   default. This is their size. A page-level .phero/.chero rule still outranks it, so the
   hero pages are unaffected. */
.awrap h1 { font-size: clamp(27px, 5.6vw, 38px); }


/* ---- TB light: REVERTED to the original (2026-08-19) ----------------------------
 * "Add the lighting on the PC how it was originally, the multiple spots. On the PC it was
 *  fine. The phone is the problem, because of the small screen the readability is hard."
 *
 * That is the clearest read anyone has had of this all week, and it moves the fix off the
 * colour entirely. Every .stage.tb override is deleted: no neutral, no blue, no top-only arc,
 * no lightless variant. TB pages fall through to the same .stage::after every Arthur page
 * uses, and var(--accent) resolves to their own #ff5705 - the three pools, in orange, exactly
 * as it was before any of tonight.
 * The phone gets a different answer instead, below: fewer LAYERS, not a different hue.
 */

/* (2026-08-19) The TB footer carried a warm pool for about an hour. Reverted at his
   request - "make the TB footer the same as it was before we started touching it" - so
   these footers are back on the shared footerBlend treatment every other page uses: flat
   #070a12 with the fade above it, and nothing TB-specific at all. */

/* ⚠️ 2026-08-19 - THE CAREERS-ONLY GLOW IS GONE, and the reason is a good one to keep.
   I gave this page a taller 20vh arc because its hero used to be long, so the standard glow
   died almost immediately and looked mean. Then I SHORTENED the hero in the same change -
   eyebrow removed, two paragraphs down to one - which pulled the first body line up to 146px,
   under a glow now reaching 162. Measuring caught it: I had broken the one rule this design
   exists to keep, with the tweak meant to serve it.
   The page no longer needs the exception - a short hero means the shared arc covers a good
   share of it. One rule for all three TB pages, and it is 16vh so there is real margin rather
   than the 8px a 17vh version would have left here. */


/* ---- PHONE: the light stays, the busy layers go (2026-08-19) --------------------
 * His diagnosis, and it is the right one: "the phone is the problem, because of the small
 * screen the readability is hard. I'm struggling to read this. And a big problem is the
 * stars." A phone is one column with no margins, so THREE decorative layers - stars,
 * drifting marks and a wash - all stack up behind the same words. A desktop spreads the
 * same three across wide empty gutters and they never collide with a line of text.
 *
 * So the phone keeps ONE layer, the light, and loses the two that sit closest to the type:
 *   #bgart / #bgart2   the drifting brand marks
 *   #sitesky           the starfield
 * Both keep working at every width above 640px, which is what he asked for - "remove them
 * from the phone only, don't remove them from the PC yet."
 *
 * ⚠️ This REPLACES the block that removed the lighting on phones an hour ago. That was the
 * same instinct aimed at the wrong layer: the wash is the one that reads as depth, the stars
 * and the marks are the ones that read as clutter at 375px. */
@media (max-width: 640px) {
  #bgart, #bgart2 { display: none !important; }
  #sitesky { display: none !important; }
}


/* ---- PC + SITE ONLY: the light gets a SOURCE (2026-08-21) ----------------------
 * Panos, on the desktop site the same night the stars came off: "make the light come
 * from specific places. Right now it feels like the light comes from everywhere. It
 * doesn't fully make sense."
 * He is describing the third pool. The shared .stage::after lights the top-right
 * corner, the bottom-left corner AND a 1100x900 pool straight through the middle of
 * the screen, so every part of the page is lit the same and nothing has a direction.
 * That centre pool was added so the middle would not read as dead space between two
 * corner glows; with the starfield gone it is the thing making the page look flat.
 *
 * So: ONE key light off the top-right, its spill falling down and to the left, and a
 * weak bounce off the bottom-left. A lit side and a dark side, which is what reads as
 * a real light. Same accent, same drift (bgBloom still animates this layer), same
 * inset:-220px oversize so no animated edge can slide into view.
 *
 * Measured at 1440x900 on /features, average brightness per corner:
 *   before  top-right 29, bottom-left 20  (1.45x, and the two top corners were equal)
 *   after   top-right 34, bottom-left 14  (2.4x)
 * That ratio IS the direction. The lit half is also brighter than before, not just the
 * dark half darker, or the page reads dead rather than lit from one side.
 *
 * SCOPED TWICE, on purpose:
 *   :not(.app)          the APP shares this stylesheet and its body IS the stage
 *                       (<body class="stage app">). Nothing here touches the app.
 *   min-width:641px     the phone is settled and he likes it. Below 641 the shared
 *                       three-pool rule still applies, untouched.
 *
 * TO MOVE THE LIGHT: change the two `at` positions. They are measured in the ::after
 * box, which is the viewport plus 220px on every side, so "84% 2%" is just above the
 * top-right CORNER of the screen, not inside it. Bigger % = further right / further
 * down. Swap 84% for 16% and 2% for 98% to light it from the other diagonal. */
@media (min-width: 641px) {
  .stage:not(.app)::after {
    opacity: .27;
    background:
      /* the key: one source, just outside the top-right corner */
      radial-gradient(1120px 880px at 84% 2%, var(--accent), transparent 62%),
      /* its spill, falling across the page so the far corner stays darker */
      linear-gradient(206deg,
        color-mix(in srgb, var(--accent) 38%, transparent) 0%, transparent 55%),
      /* the bounce back off the bottom-left, weak enough to read as reflection */
      radial-gradient(680px 560px at 2% 100%,
        color-mix(in srgb, var(--accent) 55%, transparent), transparent 64%);
  }
}
