/* ============================================================================
 * EPAL GROUP ERP  ·  assets/atmosphere/interior-scene.css
 * ----------------------------------------------------------------------------
 * THE INTERIORS AMBIENT ROOM — a living room that BUILDS ITSELF AS YOU SCROLL,
 * behind the Woodart Interiors workspace. A single scroll-progress variable
 * `--p` (0 at the top of the page → 1 at the bottom, written by interior-scene.js)
 * cross-fades three phases over an always-present room shell:
 *
 *   --p 0.0 → 0.5   THE DRAFT    blueprint floor grid, dimension lines, a
 *                                drafting set-square + compass, wood swatches
 *   --p 0.2 → 0.6   THE FIT-OUT  furniture slides up and settles (sofa, rug,
 *                                table, chair, shelves, plant, floor lamp)
 *   --p 0.55 → 1.0  THE REVEAL   lamps warm up, the window turns golden, light
 *                                pools spill on the floor, dust motes drift
 *
 * DESIGN LAW (identical to the airport scene):
 *   1. Background only — #view content paints on top (z-index 1); low master
 *      opacity, breathes through the negative space.
 *   2. One brand hue for all line-art; only lamps + window carry warm light.
 *   3. GPU-only (transform/opacity). Freezes under prefers-reduced-motion;
 *      pauses when the tab is hidden OR the vertical isn't active.
 *
 * BINDING: interior-scene.js injects `.iscene` as the first child of `.main`
 *   (behind #view), toggles `.on` for woodart, and writes `--p` on scroll.
 * ========================================================================== */

/* .main is already position:relative + #view z-index:1 (set by travels-scene.css,
   which loads first). Guard here too in case this ships standalone. */
.main { position: relative; }
.main > #view { position: relative; z-index: 1; }

/* On Interiors the full room replaces the small corner emblem (atmosphere.css). */
[data-atmos="woodart"]#view::before { display: none; }

.iscene{
  position: absolute; inset: var(--topbar-h, 62px) 0 0 0; z-index: 0;
  overflow: hidden; pointer-events: none;
  opacity: 0; transition: opacity .9s var(--e-out, ease);
  --p: 0;                   /* scroll progress, written by JS */
  /* ---- DARK (evening styled room): warm lamplight on the navy canvas ---- */
  --ink:      #7E9AE8;      /* furniture + wall line-art          */
  --ink-soft: rgba(126,154,232,.5);
  --line:     rgba(126,154,232,.7);
  --warm:     #ffbe72;      /* lamplight / golden-hour window     */
  --warm-2:   #ff9f5a;
  --glass:    #2a3f74;      /* daytime window fill                */
  --master:   .58;
}
[data-theme="light"] .iscene{
  /* ---- LIGHT (airy daytime room): soft navy line-art on pearl ---- */
  --ink:      #1A43BF;
  --ink-soft: rgba(26,67,191,.32);
  --line:     rgba(26,67,191,.5);
  --warm:     #e0912f;
  --warm-2:   #d3691e;
  --glass:    #bcd2ff;
  --master:   .34;
}
.iscene.on{ opacity: var(--master); }

/* pause when hidden OR when the vertical isn't active (no wasted compositing) */
.iscene.paused *, .iscene:not(.on) *{ animation-play-state: paused !important; }

/* seat the room into the frame with a gentle vignette */
.iscene::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  box-shadow: inset 0 -5vmin 12vmin -7vmin color-mix(in srgb, var(--bg, #00072D) 58%, transparent),
              inset 0 6vmin 15vmin -11vmin color-mix(in srgb, var(--bg, #00072D) 44%, transparent);
}
/* a soft warmth that grows into the room as you reach the reveal */
.i-haze{
  position:absolute; inset:0;
  background: radial-gradient(80% 60% at 78% 34%, color-mix(in srgb, var(--warm) 26%, transparent), transparent 60%);
  opacity: clamp(0, calc((var(--p) - 0.5) / 0.45), 1); transition: opacity .2s linear;
}

/* --------------------------------------------------------------- svg base */
.iscene-art{ position:absolute; inset:0; width:100%; height:100%; display:block; color: var(--ink); }
.iscene-art line, .iscene-art path, .iscene-art rect, .iscene-art ellipse, .iscene-art circle{
  vector-effect: non-scaling-stroke;
}

/* the world pans a touch left as the page scrolls — a gentle camera move */
.i-world{ transform: translateX(calc(var(--p) * -46px)); transition: transform .18s linear; }

/* room shell — always present, drawn in fine line */
.r-line { stroke: var(--line); stroke-width: 1.6; fill:none; }
.r-line-s{ stroke: color-mix(in srgb, var(--ink) 60%, transparent); stroke-width: 1.3; fill:none; }
.r-skirt{ stroke: var(--ink-soft); stroke-width: 3; }
.r-sill { stroke: var(--line); stroke-width: 2.4; }
.r-art  { stroke: var(--ink-soft); stroke-width: 1.4; fill:none; }
/* the window glass: cool by day, warms toward golden hour with scroll */
.win-glass{
  fill: color-mix(in srgb, var(--glass) calc(60% - var(--p) * 10%), transparent);
  transition: fill .25s linear;
}

/* ---- THE DRAFT: blueprint, fades out as furniture arrives -------------- */
.i-draft{ opacity: clamp(0, calc((0.5 - var(--p)) / 0.42), 1); transition: opacity .18s linear; }
.d-grid { stroke: var(--ink-soft); stroke-width: 1; opacity:.5; }
.d-dim  { stroke: var(--ink-soft); stroke-width: 1.2; fill:none; }
.d-tool { stroke: color-mix(in srgb, var(--ink) 65%, transparent); stroke-width: 1.4; fill:none; }
.d-arc  { stroke-dasharray: 3 6; }
.d-swatch rect{ fill: none; stroke: var(--ink-soft); stroke-width: 1.2; }
.d-swatch path{ stroke: var(--ink-soft); stroke-width: 1; fill:none; }
/* the compass arc quietly re-draws itself — a hand sketching */
.iscene.on .d-arc{ stroke-dasharray: 200; animation: d-draw 7s ease-in-out infinite; }
@keyframes d-draw{ 0%{ stroke-dashoffset:200; } 45%,55%{ stroke-dashoffset:0; } 100%{ stroke-dashoffset:-200; } }

/* ---- THE FIT-OUT: furniture builds in, each piece a touch after the last */
.i-fitout{ opacity: clamp(0, calc((var(--p) - 0.18) / 0.32), 1); transition: opacity .18s linear; }
.i-fitout .fi{
  fill: none; stroke: var(--line); stroke-width: 1.7; stroke-linejoin: round; stroke-linecap: round;
  /* slide up + settle; staggered by --d so pieces arrive in sequence */
  transform: translateY(calc((1 - clamp(0, calc((var(--p) - 0.14 - var(--d,0) * 0.05) / 0.28), 1)) * 30px));
  transition: transform .2s linear;
}
.i-fitout .rug{ stroke-width: 1.4; }
.i-fitout .rug-in{ stroke: var(--ink-soft); }
.p-shade{ fill: color-mix(in srgb, var(--ink) 12%, transparent); }
.i-warm { fill: var(--warm); stroke: none; }      /* lamp/pendant glow, lit in reveal */
.i-warm2{ stroke: var(--warm-2); }

/* pendant sways from its ceiling anchor at all times */
.p-cord{ stroke: var(--ink-soft); stroke-width: 1.4; }
.p-shade{ stroke: var(--line); stroke-width: 1.7; }
.p-bulb{ stroke: none; }
.i-pendant{ transform-box: view-box; transform-origin: 770px 96px; }
.iscene.on .i-pendant{ animation: sway 7.5s ease-in-out infinite; }
@keyframes sway{ 0%,100%{ transform: rotate(-1.6deg); } 50%{ transform: rotate(1.6deg); } }

/* plant fronds breathe */
.i-plant .frond{ stroke: var(--line); stroke-width: 1.7; fill:none; }
.i-plant{ transform-box: fill-box; transform-origin: 50% 100%; }
.iscene.on .i-plant{ animation: breathe 9s ease-in-out infinite; }
@keyframes breathe{ 0%,100%{ transform: rotate(-1.1deg) scaleY(1); } 50%{ transform: rotate(1.1deg) scaleY(1.02); } }

/* ---- THE REVEAL: lamps warm, window glows, motes drift ----------------- */
.i-reveal{ opacity: clamp(0, calc((var(--p) - 0.55) / 0.4), 1); transition: opacity .2s linear; }
.pool{ fill: var(--warm); opacity:.14; filter: blur(6px); }
.beam{ fill: var(--warm); opacity:.06; }
.mote{ fill: var(--warm); opacity:0; }
.iscene.on .i-reveal .mote{ animation: mote-rise 9s ease-in-out infinite; animation-delay: calc(var(--m,0) * -1.2s); }
@keyframes mote-rise{
  0%{ transform: translateY(24px); opacity:0; }
  30%,70%{ opacity:.7; }
  100%{ transform: translateY(-70px); opacity:0; }
}
/* the warm lamp/pendant/candle/sconce glows fade in only for the reveal, then
   pulse gently. (--p drives the fade so it works cross-branch.) */
.i-warm{ opacity: clamp(0, calc((var(--p) - 0.6) / 0.35), .9); transition: opacity .25s linear; }
.iscene.on .i-warm{ animation: glow 5s ease-in-out infinite; }
@keyframes glow{ 0%,100%{ filter: brightness(1); } 50%{ filter: brightness(1.35); } }

/* ---- WALL FIXTURES: always-present line-art (fireplace, gallery, clock…) --- */
.i-fixtures{ fill: none; stroke: var(--line); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
/* the pendulum wall-clock swings from its pivot */
.clk-pend{ transform-box: view-box; transform-origin: 1004px 214px; }
.iscene.on .clk-pend{ animation: clk-swing 2.6s ease-in-out infinite; }
@keyframes clk-swing{ 0%,100%{ transform: rotate(7deg); } 50%{ transform: rotate(-7deg); } }
/* window curtains breathe on the draught */
.curtain{ transform-box: fill-box; transform-origin: 50% 0%; }
.iscene.on .curtain-l{ animation: curtain-breathe 8.5s ease-in-out infinite; }
.iscene.on .curtain-r{ animation: curtain-breathe 8.5s ease-in-out infinite reverse; }
@keyframes curtain-breathe{ 0%,100%{ transform: skewX(0deg) scaleX(1); } 50%{ transform: skewX(2.2deg) scaleX(1.05); } }
/* hanging macramé plant sways from its hook */
.i-hangplant .frond{ stroke: var(--line); stroke-width: 1.6; fill:none; }
.i-hangplant{ transform-box: fill-box; transform-origin: 50% 0%; }
.iscene.on .i-hangplant{ animation: hp-sway 6.6s ease-in-out infinite; }
@keyframes hp-sway{ 0%,100%{ transform: rotate(-2.6deg); } 50%{ transform: rotate(2.6deg); } }

/* ---- FIT-OUT extras: cat, turntable, herringbone floor ------------------- */
/* the cat breathes softly */
.i-cat{ transform-box: fill-box; transform-origin: 50% 100%; }
.iscene.on .i-cat{ animation: cat-breathe 4.6s ease-in-out infinite; }
@keyframes cat-breathe{ 0%,100%{ transform: scaleY(1); } 50%{ transform: scaleY(1.06); } }
/* the record spins */
.tt-mark{ stroke: var(--ink-soft); }
.i-turntable{ transform-box: fill-box; transform-origin: 50% 50%; }
.iscene.on .i-turntable{ animation: tt-spin 3.4s linear infinite; }
@keyframes tt-spin{ to{ transform: rotate(360deg); } }
/* herringbone parquet, drawn faint */
.i-floor{ fill: none; stroke: var(--ink-soft); stroke-width: 1; }

/* ---- REVEAL extras: hearth flames, moon + stars, coffee steam ------------ */
.hearth-glow{ opacity: .22; }
.flame{ fill: var(--warm); stroke: none; transform-box: fill-box; transform-origin: 50% 100%; }
.flame-b{ fill: var(--warm-2); }
.iscene.on .flame-a{ animation: flick 0.9s ease-in-out infinite; }
.iscene.on .flame-b{ animation: flick 0.7s ease-in-out infinite reverse; }
@keyframes flick{ 0%,100%{ transform: scaleY(1) scaleX(1); opacity:.85; } 50%{ transform: scaleY(1.18) scaleX(.9); opacity:1; } }
.i-moon{ fill: color-mix(in srgb, var(--warm) 55%, #ffffff); stroke:none; opacity:.5; }
.i-moon-halo{ fill: var(--warm); stroke:none; opacity:.08; filter: blur(6px); }
.nstar{ fill: color-mix(in srgb, var(--warm) 30%, #eaf3ff); stroke:none; }
.iscene.on .i-reveal .nstar{ animation: nstar-twinkle 4s ease-in-out infinite; }
.nstar:nth-of-type(2n){ animation-delay: -1.6s; } .nstar:nth-of-type(3n){ animation-delay: -2.7s; }
@keyframes nstar-twinkle{ 0%,100%{ opacity:.2; } 50%{ opacity:.7; } }
.steam{ fill:none; stroke: var(--warm); stroke-width: 2; stroke-linecap: round; opacity:0; }
.iscene.on .i-reveal .steam{ animation: steam-rise 5s ease-in-out infinite; animation-delay: calc(var(--s,0) * -2.5s); }
@keyframes steam-rise{ 0%{ transform: translateY(8px); opacity:0; } 30%,60%{ opacity:.5; } 100%{ transform: translateY(-26px); opacity:0; } }

/* ============================================================================
 * THE UPPER BAND — the strip that never gets covered.
 * ----------------------------------------------------------------------------
 * WHY THIS EXISTS (owner, 2026-07-27): the room below is drawn with
 * `preserveAspectRatio="xMidYMax slice"`, i.e. anchored to the BOTTOM of the
 * viewBox — so on a normal screen its ceiling (y 0..160) is cropped away
 * entirely. Meanwhile the top of every page — behind the breadcrumb, the page
 * head and the tab band — is the ONE strip that content never fully covers, and
 * it was reading as dead space.
 *
 * So this is a SECOND, independent layer anchored to the TOP (`xMidYMin`),
 * sized in vh so it always lands exactly in that strip whatever the viewport.
 * It carries the interior motifs that read well small and repeat forever:
 * a cornice + blueprint grid, a lighting rail of swaying pendants, a gallery
 * of framed pieces, material swatch chips drifting past, a dimension line that
 * re-measures itself, and a slow warm light sweep.
 *
 * It deliberately does NOT respond to `--p`: this strip is visible at every
 * scroll position, so tying it to scroll progress would make it blink out
 * exactly where it is most wanted.
 *
 * Same three laws as the room: background only (content paints on top at
 * z-index 1), one brand hue for line-art with warmth reserved for lamps, and
 * GPU-only transforms that pause when hidden and freeze under reduced motion.
 * ========================================================================== */
.i-band{
  position:absolute; top:0; left:0; right:0;
  height: clamp(190px, 27vh, 320px);
  pointer-events:none;
  /* Sits behind real text, so it stays line-art and low-contrast — but it has
     to actually READ as a room, which the first pass did not. */
  opacity: .9;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
}
/* Light theme starts from a much lower-contrast palette (navy line on pearl),
   so the same numbers read as "nearly invisible" there. Lift the band a little
   and firm up only its structural strokes — enough to be seen, still clearly
   background. Scoped to .i-band so the room below is untouched. */
[data-theme="light"] .i-band{ opacity: .85; }
[data-theme="light"] .i-band .b-cornice,
[data-theme="light"] .i-band .b-rail,
[data-theme="light"] .i-band .b-solid,
[data-theme="light"] .i-band .b-frame,
[data-theme="light"] .i-band .b-shade{ stroke: rgba(26, 67, 191, .58); }
.i-band-art{ position:absolute; inset:0; width:100%; height:100%; display:block; color: var(--ink); }
.i-band-art line, .i-band-art path, .i-band-art rect, .i-band-art circle, .i-band-art ellipse{
  vector-effect: non-scaling-stroke;
}

/* cornice + the faint blueprint grid that fades as it falls away from it */
.b-cornice{ stroke: var(--line); stroke-width: 1.8; fill:none; }
.b-cornice-s{ stroke: var(--ink-soft); stroke-width: 1.2; fill:none; }
.b-grid{ stroke: var(--ink-soft); stroke-width: 1; opacity:.34; }

/* the pieces that make it read as a ROOM at a glance, not just geometry */
.b-solid{ stroke: var(--line); stroke-width: 1.7; fill:none; stroke-linejoin:round; stroke-linecap:round; }
.b-soft { stroke: var(--ink-soft); stroke-width: 1.3; fill:none; stroke-linecap:round; }
/* the potted palm breathes */
.b-plant{ transform-box: fill-box; transform-origin: 50% 100%; }
.iscene.on .b-plant{ animation: b-breathe 11s ease-in-out infinite; }
@keyframes b-breathe{ 0%,100%{ transform: rotate(-1.1deg); } 50%{ transform: rotate(1.1deg); } }

/* ---- lighting rail: pendants on a track, each swaying on its own phase --- */
.b-rail{ stroke: var(--line); stroke-width: 1.8; fill:none; }
.b-pend{ transform-box: fill-box; transform-origin: 50% 0%; }
.iscene.on .b-pend{ animation: b-sway 9s ease-in-out infinite; animation-delay: calc(var(--i,0) * -1.35s); }
@keyframes b-sway{ 0%,100%{ transform: rotate(-1.9deg); } 50%{ transform: rotate(1.9deg); } }
.b-cord{ stroke: var(--ink-soft); stroke-width: 1.2; }
.b-shade{ stroke: var(--line); stroke-width: 1.6; fill: color-mix(in srgb, var(--ink) 10%, transparent); }
.b-bulb{ fill: var(--warm); stroke:none; opacity:.75; }
.iscene.on .b-bulb{ animation: b-glow 6s ease-in-out infinite; animation-delay: calc(var(--i,0) * -0.9s); }
@keyframes b-glow{ 0%,100%{ opacity:.42; } 50%{ opacity:.95; } }
.b-pool{ fill: var(--warm); stroke:none; opacity:.10; filter: blur(7px); }
.iscene.on .b-pool{ animation: b-pool 6s ease-in-out infinite; animation-delay: calc(var(--i,0) * -0.9s); }
@keyframes b-pool{ 0%,100%{ opacity:.05; } 50%{ opacity:.16; } }

/* ---- gallery wall: framed pieces, one slowly "levelling" itself ---------- */
.b-frame{ stroke: var(--line); stroke-width: 1.5; fill:none; }
.b-frame-in{ stroke: var(--ink-soft); stroke-width: 1; fill:none; }
.b-tilt{ transform-box: fill-box; transform-origin: 50% 0%; }
.iscene.on .b-tilt{ animation: b-level 13s ease-in-out infinite; }
@keyframes b-level{ 0%,100%{ transform: rotate(-1.4deg); } 45%,62%{ transform: rotate(0deg); } }

/* ---- material swatches drifting past, like samples on a bench ------------ */
.b-chip rect{ stroke: var(--ink-soft); stroke-width: 1.1; fill: color-mix(in srgb, var(--ink) 7%, transparent); }
.b-chip path{ stroke: var(--ink-soft); stroke-width: .9; fill:none; }   /* grain / weave */
.iscene.on .b-chip{ animation: b-drift 46s linear infinite; animation-delay: calc(var(--i,0) * -9s); }
@keyframes b-drift{ 0%{ transform: translateX(1660px); } 100%{ transform: translateX(-260px); } }

/* ---- a dimension line that re-measures itself, forever ------------------- */
.b-dim{ stroke: var(--ink-soft); stroke-width: 1.2; fill:none; }
.b-dim-run{ stroke-dasharray: 340; }
.iscene.on .b-dim-run{ animation: b-measure 11s ease-in-out infinite; }
@keyframes b-measure{
  0%{ stroke-dashoffset: 340; } 40%,60%{ stroke-dashoffset: 0; } 100%{ stroke-dashoffset: -340; }
}
.b-tick{ stroke: var(--ink-soft); stroke-width: 1.2; }

/* ---- the slow warm sweep — a shaft of light crossing the room ------------ */
.b-sweep{
  fill: var(--warm); stroke:none; opacity:0;
  transform-box: fill-box;
}
.iscene.on .b-sweep{ animation: b-sweep 26s ease-in-out infinite; }
@keyframes b-sweep{
  0%   { transform: translateX(-340px) skewX(-14deg); opacity:0; }
  18%  { opacity:.10; }
  50%  { opacity:.055; }
  82%  { opacity:.10; }
  100% { transform: translateX(1700px) skewX(-14deg); opacity:0; }
}

/* ------------------------------------------------ reduced motion → freeze */
@media (prefers-reduced-motion: reduce){
  .iscene *{ animation: none !important; }
  .i-world{ transition: none; }
  /* land on a calm, fully-furnished, softly-lit room */
  .iscene{ --p: .72; }
  /* the band still reads as a finished room, just still: park the drifting
     swatches off-stage rather than leaving them stacked at their start point,
     and hide the light sweep, which is only meaningful in motion. */
  .b-chip{ opacity: 0; }
  .b-sweep{ opacity: 0; }
}

/* On a short viewport the band would crowd the page head — shrink it rather
   than let it compete with the title. */
@media (max-height: 620px){ .i-band{ height: 150px; opacity:.45; } }
