/*
 * welcome-hemisphere.css — Stage 2A / Run 10C
 *
 * Scope: the welcome screen ONLY. Every selector is prefixed with `#screen-welcome`
 * so nothing here can reach Home, Search, Playlists, Player or Settings. The slider
 * is deliberately absent from this file: it keeps its accepted markup, styles and
 * JavaScript, and this layout is built around it rather than over it.
 *
 * Geometry contract:
 *   --hemi-r      radius of the disc, in px, published by JS from the measured stage
 *   --hemi-cy     vertical centre of the disc == vertical centre of the usable stage
 *
 * The disc is a FULL circle whose centre sits on the left viewport edge. That is what
 * makes it read as a hemisphere protruding from the left instead of a floating circle,
 * and it is also what makes the vertical balance measurable: top gap and bottom gap are
 * computed from the same centre, so they are equal by construction rather than by eye.
 */

/* ---------------------------------------------------------------- stage ---- */
#screen-welcome .welcome-stage--hemisphere {
  position: absolute;
  inset: 0;
  overflow: clip;
  /*
   * The layer stack for the whole scene. The gradient sits at 0, the disc at 1, its
   * specular detail at 2, the text at 3. The CTA keeps its own higher stacking from
   * screens.css, so it can never be occluded by the glass.
   */
  isolation: isolate;
  /*
   * Baseline burgundy/black field. Deep near-black at the edges, wine in the middle,
   * a restrained warm bloom where the disc sits. No image, no raster texture.
   */
  background:
    radial-gradient(120% 80% at 18% 46%, rgba(240, 106, 85, 0.16) 0%, rgba(240, 106, 85, 0) 52%),
    radial-gradient(90% 70% at 8% 22%, rgba(91, 25, 31, 0.55) 0%, rgba(91, 25, 31, 0) 60%),
    radial-gradient(110% 90% at 96% 82%, rgba(38, 13, 19, 0.85) 0%, rgba(38, 13, 19, 0) 62%),
    linear-gradient(168deg, #0b090c 0%, #150a10 34%, #260d13 62%, #0b090c 100%);
}

/*
 * Soft coral bloom, offset behind the disc so the glass has something to refract.
 * A separate layer (not part of the background shorthand) because it must sit above
 * the disc's own fill to be visible through the blur.
 */
#screen-welcome .aura {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /*
   * Structure for the glass to refract.
   *
   * A blur over a perfectly smooth gradient is invisible — there is nothing to smear.
   * These soft blooms sit BEHIND the disc and are what the backdrop-filter visibly
   * distorts at the disc's boundary. Without them the panel can only ever read as a
   * translucent tint, which is exactly what the first pass looked like.
   */
  background:
    radial-gradient(32% 22% at 30% 24%, rgba(240, 106, 85, 0.34) 0%, rgba(240, 106, 85, 0) 68%),
    radial-gradient(26% 18% at 14% 52%, rgba(255, 143, 107, 0.26) 0%, rgba(255, 143, 107, 0) 70%),
    radial-gradient(30% 24% at 22% 78%, rgba(159, 75, 51, 0.30) 0%, rgba(159, 75, 51, 0) 72%),
    radial-gradient(18% 12% at 44% 46%, rgba(255, 196, 170, 0.16) 0%, rgba(255, 196, 170, 0) 72%);
}

/* ------------------------------------------------------------ hemisphere ---- */
#screen-welcome .hemi {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
}

/*
 * The disc itself.
 *
 * Sized from --hemi-r (published by JS) and positioned so its centre is at x=0 —
 * the left edge — and y=--hemi-cy. `left: calc(-1 * var(--hemi-r))` is what puts the
 * centre exactly on the edge: the box's left edge is one radius to the left of the
 * centre, so half the circle is always off-screen, at every width.
 */
#screen-welcome .hemi-disc {
  position: absolute;
  left: calc(-1 * var(--hemi-r));
  top: calc(var(--hemi-cy) - var(--hemi-r));
  width: calc(var(--hemi-r) * 2);
  height: calc(var(--hemi-r) * 2);
  border-radius: 50%;
  /*
   * Frosted glass, layered rather than a flat fill:
   *   1. a diagonal sheen across the surface,
   *   2. a wine-charcoal wash that keeps the gradient readable through it,
   *   3. the blur that lets the backdrop actually show through.
   * Alpha stays low enough that the burgundy field is clearly visible inside the disc —
   * a solid fill would break the whole point of the element.
   */
  background:
    linear-gradient(132deg,
      rgba(255, 248, 246, 0.13) 0%,
      rgba(255, 248, 246, 0.05) 18%,
      rgba(38, 13, 19, 0.26) 46%,
      rgba(11, 9, 12, 0.34) 100%),
    linear-gradient(160deg, rgba(91, 25, 31, 0.30) 0%, rgba(11, 9, 12, 0.20) 100%);
  -webkit-backdrop-filter: blur(34px) saturate(165%) brightness(1.10) contrast(1.04);
  backdrop-filter: blur(34px) saturate(165%) brightness(1.10) contrast(1.04);
  box-shadow:
    /* tight inner rim, the "thickness" of the glass */
    inset 0 0 1px rgba(255, 248, 246, 0.35),
    /* broad inner glow, light caught inside the material */
    inset 28px -10px 90px -30px rgba(255, 248, 246, 0.20),
    inset -40px 40px 120px -50px rgba(240, 106, 85, 0.16),
    /* the drop shadow that separates glass from background */
    0 40px 90px -40px rgba(0, 0, 0, 0.75),
    0 8px 24px -12px rgba(0, 0, 0, 0.6);
}

/*
 * Specular highlight: an off-centre soft ellipse riding the upper-left of the sphere,
 * plus a short bright arc where the curved surface catches the light. Kept as a
 * separate element so it can overlap the disc edge without widening the disc's own
 * box shadows.
 */
#screen-welcome .hemi-specular {
  position: absolute;
  left: calc(-1 * var(--hemi-r));
  top: calc(var(--hemi-cy) - var(--hemi-r));
  width: calc(var(--hemi-r) * 2);
  height: calc(var(--hemi-r) * 2);
  border-radius: 50%;
  z-index: 2;
  pointer-events: none;
  background:
    radial-gradient(38% 26% at 62% 26%, rgba(255, 248, 246, 0.20) 0%, rgba(255, 248, 246, 0) 72%),
    radial-gradient(26% 18% at 78% 62%, rgba(255, 214, 196, 0.12) 0%, rgba(255, 214, 196, 0) 74%);
  mix-blend-mode: screen;
}

/*
 * Hairline rim on the visible right boundary. Drawn as a ring that is only visible on
 * the half that is on screen — a full border would put a bright line across the
 * screen edge, which reads as a seam rather than glass.
 */
#screen-welcome .hemi-rim {
  position: absolute;
  left: calc(-1 * var(--hemi-r));
  top: calc(var(--hemi-cy) - var(--hemi-r));
  width: calc(var(--hemi-r) * 2);
  height: calc(var(--hemi-r) * 2);
  border-radius: 50%;
  z-index: 2;
  pointer-events: none;
  border: 1px solid rgba(255, 248, 246, 0.16);
  border-left-color: transparent;
  border-bottom-color: rgba(255, 248, 246, 0.07);
  mask-image: linear-gradient(90deg, transparent 46%, #000 52%, #000 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 46%, #000 52%, #000 100%);
}

/* --------------------------------------------------------------- content ---- */
/*
 * Text and controls live inside the VISIBLE half of the disc. Their container starts at
 * the screen edge and is capped well before the disc's right boundary, so no glyph can
 * spill past the curve at any width — the cap comes from the same --hemi-r.
 */
/*
 * Content block — Run 10D.
 *
 * Two changes, both measured rather than eyeballed:
 *
 * 1. ONE shared left guide. Every child starts at the same x, set once here, instead of
 *    each element carrying its own padding. Waveform, headline, underline, subtitle and
 *    the three dots are left-aligned to that guide, near the screen's safe edge — not
 *    centred inside the visible half-circle.
 *
 * 2. The WHOLE GROUP is vertically centred on the disc's centre, not just the headline.
 *    `top: var(--hemi-cy); transform: translateY(-50%)` centres the group's own box on
 *    the sphere axis. The previous version used
 *    `top: calc(var(--hemi-cy) - var(--hemi-r) * 0.78)`, which parked the block in the
 *    upper part of the glass — the owner's complaint, confirmed by measurement at 68 px
 *    above centre at 390.
 */
#screen-welcome .hemi-content {
  --welcome-content-inset: 18px;

  position: absolute;
  left: var(--welcome-content-inset);
  top: var(--hemi-cy);
  transform: translateY(-50%);
  /*
   * Width is bounded by the glass at the group's own vertical position, not by the disc's
   * widest point. At the sphere's vertical centre the visible chord is the FULL diameter
   * half-width, so the radius is the honest cap; the extra 24px keeps glyphs off the rim.
   */
  width: min(calc(var(--hemi-r) - 38px), calc(100vw - var(--welcome-content-inset) * 2));
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 9px;
  pointer-events: none;
  /* No centring anywhere in this block: the brief forbids text-align/margin auto. */
  text-align: left;
}

#screen-welcome .hemi-content > * {
  pointer-events: auto;
}

/* Coral waveform: seven bars, varied heights, rounded ends. Decorative only. */
#screen-welcome .wave-mark--coral {
  display: inline-flex;
  align-items: flex-end;
  gap: 4px;
  height: 26px;
  margin-bottom: 4px;
}

#screen-welcome .wave-mark--coral i {
  display: block;
  width: 4px;
  border-radius: 3px;
  background: linear-gradient(180deg, #ff8f6b 0%, #f06a55 60%, #c9483a 100%);
  box-shadow: 0 0 14px -2px rgba(240, 106, 85, 0.55);
}

#screen-welcome .wave-mark--coral i:nth-child(1) { height: 9px;  }
#screen-welcome .wave-mark--coral i:nth-child(2) { height: 18px; }
#screen-welcome .wave-mark--coral i:nth-child(3) { height: 13px; }
#screen-welcome .wave-mark--coral i:nth-child(4) { height: 26px; }
#screen-welcome .wave-mark--coral i:nth-child(5) { height: 16px; }
#screen-welcome .wave-mark--coral i:nth-child(6) { height: 21px; }
#screen-welcome .wave-mark--coral i:nth-child(7) { height: 11px; }

/*
 * Typography — Run 10D.
 *
 * The previous heading was 800-weight, upright, 1.06 line-height and -0.038em tracking:
 * a compressed grotesque. The owner's reference is an editorial italic with a lighter
 * gesture, so this uses the system serif-adjacent stack the project already ships with
 * (no downloads), oblique at ~640 weight, a wider line-height and almost no negative
 * tracking. The coral accent stays on the middle line.
 *
 * `em` keeps its emphasis semantics and inherits the same italic, so the accent line reads
 * as part of the same sentence rather than a different typeface.
 */
#screen-welcome .welcome-title {
  margin: 0;
  font-family: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
    Georgia, ui-serif, serif;
  /*
   * Run 10E: the display size was still oversized (28.1px at 390, 31px at 430) and the
   * longer slide-2/3 phrases ran into the curved rim. The owner asked for a smaller,
   * editorial heading, and the TZ suggests starting around 19-23px at 390.
   *
   * 21px at 390 sits mid-range; the vw term keeps it proportional, and the clamp ceiling
   * stops it ballooning at 430. Combined with the shorter copy this restores real rim
   * clearance instead of the 9.5px measured on the old build.
   */
  font-size: clamp(19px, 5.4vw, 23px);
  line-height: 1.2;
  font-weight: 640;
  font-style: italic;
  letter-spacing: -0.012em;
  color: #fff8f6;
  text-shadow: 0 2px 22px rgba(0, 0, 0, 0.42);
}

#screen-welcome .welcome-title em {
  font-style: italic;
  font-weight: 660;
  color: #ff8f6b;
}

/* Thin coral underline, as in the reference's text block. */
#screen-welcome .title-underline {
  display: block;
  width: 46px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, #f06a55 0%, rgba(240, 106, 85, 0.15) 100%);
}

#screen-welcome .welcome-sub {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  /* Contrast raised from 0.70: the copy sits on glass, not on flat dark. */
  color: rgba(255, 248, 246, 0.84);
  max-width: 13ch;
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.5);
}

/* Three real tab buttons. Styled for the glass, same behaviour as before. */
#screen-welcome .page-dots {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}

#screen-welcome .page-dot {
  width: 6px;
  height: 6px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 248, 246, 0.30);
  position: relative;
  cursor: pointer;
  transition: width var(--fast, 160ms) cubic-bezier(.2,.7,.3,1),
              background var(--fast, 160ms) cubic-bezier(.2,.7,.3,1);
}

#screen-welcome .page-dot::after {
  content: '';
  position: absolute;
  inset: -12px;
  border-radius: 50%;
}

#screen-welcome .page-dot[aria-selected='true'] {
  width: 18px;
  border-radius: 3px;
  background: #f06a55;
}

#screen-welcome .page-dot:focus-visible {
  outline: 2px solid #ff8f6b;
  outline-offset: 4px;
}

/* ---------------------------------------------------------- light theme ---- */
/*
 * The glass scene is a dark photographically-lit composition; inverting it would make
 * the hemisphere read as a grey blob on white. Light theme keeps the same artwork
 * structure but lifts the field into warm charcoal-wine and raises the glass alpha and
 * text contrast, so it is genuinely legible rather than a mirror of dark mode.
 */
[data-theme='light'] #screen-welcome .welcome-stage--hemisphere {
  /*
   * Genuinely lighter, not a nudge.
   *
   * The first version only shifted the wine tones a few points and measured as identical
   * to dark once the violet-coral glow dominated — a theme switch that doesn't visibly
   * switch. This palette lifts the base into warm rose-grey (base #4a3038 vs #0b090c) and
   * keeps the coral bloom, so the glass still has a dark field behind it to read as glass
   * while the screen is unmistakably the light variant.
   */
  background:
    radial-gradient(120% 80% at 18% 46%, rgba(240, 106, 85, 0.26) 0%, rgba(240, 106, 85, 0) 56%),
    radial-gradient(90% 70% at 6% 20%, rgba(168, 96, 96, 0.55) 0%, rgba(168, 96, 96, 0) 64%),
    radial-gradient(110% 90% at 96% 84%, rgba(96, 58, 64, 0.75) 0%, rgba(96, 58, 64, 0) 66%),
    linear-gradient(168deg, #4a3038 0%, #5d3a42 34%, #6b424a 60%, #3b252c 100%);
}

[data-theme='light'] #screen-welcome .hemi-disc {
  background:
    linear-gradient(132deg,
      rgba(255, 255, 255, 0.20) 0%,
      rgba(255, 255, 255, 0.08) 18%,
      rgba(74, 38, 48, 0.30) 46%,
      rgba(36, 20, 25, 0.34) 100%);
}

[data-theme='light'] #screen-welcome .welcome-sub {
  color: rgba(255, 255, 255, 0.80);
}

/* --------------------------------------------------------------- narrow ---- */
@media (max-width: 360px) {
  #screen-welcome .hemi-content { --welcome-content-inset: 15px; gap: 7px; }
  /*
   * 320 needs its own scale. The disc is 260 px there (its own target band is 265–285,
   * and the clamp floor is 130 px radius), so the visible chord is only ~130 px wide at
   * the group's centre. At the previous size the subtitle overran the curve by 22 px —
   * measured against the circle's chord at each line's own y, not against the disc's
   * widest point. Both the heading and the copy step down here rather than growing the
   * circle back, which is what the brief asks for.
   */
  #screen-welcome .welcome-title { font-size: 17px; line-height: 1.22; }
  #screen-welcome .welcome-sub { font-size: 11px; line-height: 1.45; max-width: 11ch; }
  #screen-welcome .wave-mark--coral { height: 22px; }
  #screen-welcome .wave-mark--coral i:nth-child(4) { height: 22px; }
  #screen-welcome .wave-mark--coral i:nth-child(6) { height: 18px; }
}

/*
 * Reduced motion: the glass has no animation of its own, but the aura bloom is
 * decorative and must not become a transition target by accident.
 */
@media (prefers-reduced-motion: reduce) {
  #screen-welcome .hemi-disc,
  #screen-welcome .hemi-specular,
  #screen-welcome .aura {
    transition: none;
    animation: none;
  }
}

/* ---------------------------------------------------------------- frame ---- */
/*
 * The welcome screen is a fixed, viewport-locked canvas: gradient and glass fill it,
 * and the CTA is pinned to the bottom edge over the artwork.
 *
 * Only the CONTAINER of the slider is positioned here. The slider's own markup, classes,
 * styles and JavaScript are untouched — this is the surrounding layout, which the brief
 * allows and the acceptance criteria require ("position layout around it").
 */
#screen-welcome {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100dvh;
  max-height: 100dvh;
  overflow: clip;
  background: #0b090c;
}

#screen-welcome .welcome-bg {
  display: none;          /* superseded by the gradient on the stage */
}

#screen-welcome .welcome-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
}

#screen-welcome .welcome-cta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
}

/*
 * On a desktop browser the Mini App should read as a phone, not as a stretched page.
 * Centring the canvas at a device width is the "proper Mini App canvas" the brief asks
 * for; on a real phone (<=430) this rule has no effect because the width is already
 * below the cap.
 */
@media (min-width: 431px) {
  #screen-welcome {
    left: 50%;
    right: auto;
    width: 430px;
    transform: translateX(-50%);
    border-radius: 26px;
    box-shadow: 0 40px 120px -40px rgba(0, 0, 0, 0.9);
  }
}

/* ------------------------------------------------- slider caption (320) ---- */
/*
 * Restored verbatim from the accepted Run 10B state.
 *
 * This block shipped in screens.css and was lost when the obsolete welcome rules were
 * trimmed out of that file. Without it the caption runs under the coral endpoint at 320px
 * ("…чтобы начат" instead of "…чтобы начать"). It is a CSS-only layout fix for the
 * label's box: the slider's markup, JavaScript, colours and gesture are untouched, and the
 * label keeps its text so the accessible name is unchanged.
 */
@media (max-width: 360px) {
  #screen-welcome .slide-label {
    left: 58px;
    right: 58px;
    font-size: 13px;
    letter-spacing: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #screen-welcome .welcome-cta { padding-inline: 14px; }
}

@media (max-width: 330px) {
  #screen-welcome .slide-label { font-size: 12.5px; }
}

/*
 * Edge refraction band.
 *
 * Real glass bends light hardest where the surface curves away. A thin ring just inside
 * the rim, slightly brighter and shifted in hue, is what separates "frosted glass" from
 * "translucent rounded rectangle" at a glance.
 */
#screen-welcome .hemi::after {
  content: '';
  position: absolute;
  left: calc(-1 * var(--hemi-r));
  top: calc(var(--hemi-cy) - var(--hemi-r));
  width: calc(var(--hemi-r) * 2);
  height: calc(var(--hemi-r) * 2);
  border-radius: 50%;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(closest-side,
    rgba(255, 255, 255, 0) 88%,
    rgba(255, 214, 196, 0.13) 95%,
    rgba(255, 248, 246, 0.22) 99%,
    rgba(255, 248, 246, 0) 100%);
  mask-image: linear-gradient(90deg, transparent 40%, #000 55%, #000 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 40%, #000 55%, #000 100%);
}

/* ---------------------------------------------------------------- carousel
 *
 * Run 10E. The active dot is a short coral dash, the inactive ones are small round dots,
 * all of them inside the glass on the same left guide as the copy.
 *
 * The pause control is deliberately subordinate: same row, after the dots, no chrome of its
 * own until focused or hovered. It exists because the W3C carousel pattern requires a
 * discoverable rotation control, and because a carousel that cannot be stopped is an
 * accessibility failure, not a feature.
 */
#screen-welcome .page-dots {
  /* 44px targets via hit areas, not by drawing 44px dots. */
  min-height: 24px;
}

#screen-welcome .rotation-toggle {
  position: relative;
  width: 16px;
  height: 16px;
  margin-left: 2px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(255, 248, 246, 0.55);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color var(--fast, 160ms) ease, background-color var(--fast, 160ms) ease;
}

/* Extend the tap target without enlarging the glyph. */
#screen-welcome .rotation-toggle::after {
  content: '';
  position: absolute;
  inset: -14px;
  border-radius: 50%;
}

#screen-welcome .rotation-toggle:hover,
#screen-welcome .rotation-toggle:focus-visible {
  color: #ff8f6b;
}

#screen-welcome .rotation-toggle:focus-visible {
  outline: 2px solid #ff8f6b;
  outline-offset: 3px;
}

/* Pause bars, or a play triangle when rotation is stopped. Pure CSS, no icon font. */
#screen-welcome .rotation-icon {
  width: 7px;
  height: 9px;
  position: relative;
  display: block;
}

#screen-welcome .rotation-icon::before,
#screen-welcome .rotation-icon::after {
  content: '';
  position: absolute;
  top: 0;
  width: 2px;
  height: 9px;
  border-radius: 1px;
  background: currentColor;
}

#screen-welcome .rotation-icon::before { left: 0; }
#screen-welcome .rotation-icon::after { right: 0; }

#screen-welcome .rotation-toggle.is-paused .rotation-icon::before {
  width: 0;
  height: 0;
  top: 0;
  left: 1px;
  background: transparent;
  border-left: 7px solid currentColor;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
}

#screen-welcome .rotation-toggle.is-paused .rotation-icon::after {
  content: none;
}

/*
 * The slide change itself: a short cross-fade of the copy only.
 *
 * Nothing geometric animates — the sphere, the wave and the slider must not move when the
 * carousel advances, which is why only opacity/filter are touched here.
 */
#screen-welcome .hemi-content {
  transition: opacity 220ms ease;
}

#screen-welcome.is-rotating .hemi-content {
  opacity: 0.35;
}

@media (prefers-reduced-motion: reduce) {
  #screen-welcome .hemi-content,
  #screen-welcome .rotation-toggle,
  #screen-welcome .page-dot {
    transition: none !important;
  }
}

/* ============================================================================
 * Run 10F-R8 — the photo ring: full half-annulus, real gutters, upright portraits
 *
 * Three rejections from R7 are answered structurally here:
 *
 *  1. R7 stopped at +/-82 degrees, so its outer endpoints sat at Rout*cos(82) ~= 35.7 px from
 *     the left edge. The band now runs the full -90..+90 half-annulus, and the endpoints are
 *     on x=0 by construction (cos 90 = 0), not by a nudge.
 *  2. R7's separators were 2.5 px strokes painted over one continuous band. Here the gutters
 *     are subtracted space: each wedge's angular span is shrunk by half a 6 px gap measured at
 *     the mid radius, so the backdrop shows through ~5-7 px of empty ring between photos.
 *  3. R7's rasters were pre-warped into polar shape, which bent the people. The photos are now
 *     ordinary upright <image> elements, uniformly scaled to cover their wedge and only
 *     CLIPPED by the wedge path.
 *
 * Units: the viewBox is 1000 units per 1 x R_glass. R_inner = R+2 (so nothing enters the disc)
 * and R_outer = 1.40R, matching the size the owner accepted in R7.
 * ========================================================================== */

#screen-welcome .photo-ring-wrap {
  position: absolute;
  /* Centre of the disc: the circle's origin is the left screen edge. */
  left: 0;
  top: var(--hemi-cy);
  /*
   * viewBox is 1410 x 2820 user units (R_outer on either side of the centre, plus a hair of
   * margin). Sizing the element to exactly those dimensions in disc-relative units maps one
   * user unit to one CSS pixel at 1440 units per R, which keeps the arcs circular.
   */
  /*
   * The SVG's viewBox is rewritten by photo-ring.js in CSS pixels for the live radius, and its
   * origin is the disc centre. Width/height therefore follow the outer reach directly: 1.41R
   * covers 1.40R plus the 10 px margin the viewBox keeps.
   */
  /*
   * Fallback size only: photo-ring.js writes exact pixel dimensions derived from the same
   * numbers as the viewBox, so the SVG maps 1:1 and the arcs stay circular. If the module fails
   * to load, these keep the baked 390x844 geometry roughly in place instead of collapsing.
   */
  width: calc(var(--hemi-r, 180px) * 1.41);
  height: calc(var(--hemi-r, 180px) * 2.82);
  margin-top: calc(var(--hemi-r, 180px) * -1.41);
  /*
   * Behind the whole glass stack. Inside .hemi this index competes with the disc's own
   * children (disc 1, specular/rim 2, copy 3), so a negative value puts the band behind all
   * of them while staying inside the glass stacking context.
   */
  z-index: -1;
  pointer-events: none;
  /*
   * No transform here on purpose. R7 scaled the whole SVG about the disc centre to fit short
   * screens, which moved the INNER edge inward and let photo tips appear inside the glass.
   * In R8 the reach is applied inside photo-ring.js to the outer radius only, while the inner
   * radius stays pinned at R+2, so the band gets thinner instead of creeping inward.
   */
}

#screen-welcome .photo-ring {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  /* Read by photo-ring.js to decide the outer reach; the inner edge is never scaled. */
  --ring-reach: var(--ring-reach, 1);
}

/*
 * The photos must stay expressive. R7 dimmed them with opacity and a brightness filter, which
 * the owner explicitly rejected; nothing here darkens them, and the grade is baked in.
 */
#screen-welcome .photo-ring image {
  opacity: 1;
}

/* The inner lip: a hairline where the ring's opaque occlusion meets the glass. It is not a
   separator — the four gutters are real gaps in the geometry. */
#screen-welcome .ring-inner-lip {
  stroke: rgba(255, 226, 214, 0.10);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

:root[data-theme="light"] #screen-welcome .ring-inner-lip {
  stroke: rgba(74, 48, 56, 0.18);
}

/* ---------------------------------------------------------------- responsive
 *
 * Only the OUTER reach shrinks on tight screens. R7 scaled the whole SVG about the disc centre,
 * which pulled the inner radius inward and let photo pixels creep under the glass; here the
 * inner edge is a fixed R+2 and only the outer radius is reduced.
 */
@media (max-height: 700px) {
  #screen-welcome, #screen-welcome .photo-ring { --ring-reach: 0.94; }
}

@media (max-width: 340px) {
  #screen-welcome, #screen-welcome .photo-ring { --ring-reach: 0.95; }
}

/* The band is decoration; a hidden tab must not keep it painted. */
/* The strip is decoration; a hidden tab must not keep it painted. */
#screen-welcome.is-backgrounded .photo-ring-wrap {
  visibility: hidden;
}
