/* ============================================================
   Obsidian Wing — panel content
   ============================================================ */

/* ---------- HERO ---------- */

#ow-kinetic-grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.ow-hero__stack {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 2vh, 24px);
  pointer-events: none;
  container-type: size;         /* the ring sizes itself against the stage, not the viewport */
}

.ow-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  direction: ltr;               /* left wing must stay on the left */
}

/* Proportions measured from the master mark (Frame_11.svg, viewBox 640x360)
   and cross-checked against the three exported pieces:
     left.svg 160x156 · Group-10.svg 62x125 · both cropped tight.
   wings  y 66.6 → 337.6 = 271 units
   stone  y 141.6 → 357.5 = 216 units   → stone = 80.1% of the wing height
   stone centre sits 47.5 units lower than the wing centre → 17.5% of wing height
   each wing overlaps the stone by 12.6 units            → 4.6% of wing height   */

/* The mark and wordmark are sized from the ring (min(480px, 88cqmin), see
   .ow-rotating-text) so they always sit inside its letters. Sizing them from
   the viewport height alone let the wings outgrow the ring on phones. */
.ow-mark { --ow-wing-h: clamp(90px, 17vh, 150px); }                                       /* fallback: no container units */
.ow-mark { --ow-wing-h: min(clamp(90px, 17vh, 150px), calc(min(480px, 88cqmin) * .28)); }
.ow-mark img { display: block; height: var(--ow-wing-h); width: auto; }

.ow-obsidian {
  height: calc(var(--ow-wing-h) * .801) !important;
  margin-inline: calc(var(--ow-wing-h) * -.046);
  position: relative;
  top: calc(var(--ow-wing-h) * .175);      /* not transform — the entrance animation owns that */
  z-index: 1;
}

/* kept narrow so the wordmark does not touch the ring letters */
.ow-logo-type { display: block; width: clamp(150px, 15vw, 230px); height: auto; }
.ow-logo-type { width: min(clamp(150px, 15vw, 230px), calc(min(480px, 88cqmin) * .42)); }

/* --- entrance: continues the bar beats (ow-shell.css), .55s apart ---
   2.85 stone · 3.40 wings (left, right .12s later) · 3.95 wordmark · 4.50 ring · 5.60 spin */

.ow-obsidian {
  opacity: 0;
  transform: translateY(-18px) scale(.72);
  filter: blur(8px);
  animation: owObsidianIn .9s var(--ow-ease-enter) 2.85s forwards;
}

.ow-wing-left {
  opacity: 0;
  transform: translate(42px, 18px) rotate(7deg) scale(.8);
  transform-origin: right center;
  filter: blur(7px);
  animation: owWingLeftIn .9s var(--ow-ease-enter) 3.4s forwards;
}

.ow-wing-right {
  opacity: 0;
  transform: translate(-42px, 18px) rotate(-7deg) scale(.8);
  transform-origin: left center;
  filter: blur(7px);
  animation: owWingRightIn .9s var(--ow-ease-enter) 3.52s forwards;
}

.ow-logo-type {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(6px);
  animation: owTypeIn .9s var(--ow-ease-enter) 3.95s forwards;
}

@keyframes owObsidianIn  { to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes owWingLeftIn  { to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes owWingRightIn { to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes owTypeIn      { to { opacity: 1; transform: none; filter: blur(0); } }

/* --- rotating text --- */

.ow-rotating-text {
  position: absolute;
  left: 50%;                    /* physical, not inset-inline-start: in RTL that becomes right:50% and the ring drifts */
  top: 50%;
  width: min(480px, 70vmin);    /* fallback for browsers without container units */
  height: min(480px, 70vmin);
  width: min(480px, 88cqmin);   /* relative to the stage, so the ring is never clipped */
  height: min(480px, 88cqmin);
  opacity: 0;
  transform: translate(-50%, -50%) scale(.82) rotate(-16deg);
  pointer-events: none;
  animation:
    owRingIn   1.1s var(--ow-ease-enter) 4.5s forwards,
    owRingSpin 24s  linear         5.6s infinite;
}

.ow-rotating-text svg { display: block; width: 100%; height: 100%; overflow: visible; }

.ow-rotating-text text {
  fill: #B3BAC0;                /* Neutral Silver 400 */
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 32px;         /* same as page 1 */
}

@keyframes owRingIn   { to { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); } }
@keyframes owRingSpin {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}

@media (max-width: 767px) {
  /* the two words should run all the way round, with only a small gap between
     them (Mohi, 1405/07/21; 10px and 18px left half the ring empty).
     36px: WEB DESIGNER fills ~94% of its half, UI DESIGNER ~86%. */
  .ow-rotating-text text { font-size: 18px; letter-spacing: 36px; }

  /* a larger ring on phones (Mohi, 1405/07/21). The mark and wordmark keep
     their own size: their rules above still read the old 88cqmin ring.
     The box may be a little wider than the stage — the letters sit at ~82%
     of its radius, so they stay inside (110cqmin put them ~7px from the stage edge).
     375px phone: 302px → 357px. */
  .ow-rotating-text { width: min(480px, 104cqmin); height: min(480px, 104cqmin); }
}

/* desktop: a bigger ring and mark for more presence (Mohi, 1405/07/21).
   At this ring size .28 put the wing tips on the letters, so the mark is .24
   and the wordmark .38 of the ring. 1440x900: ring 480→601, wings 134→144. */
@media (min-width: 768px) {
  .ow-rotating-text { width: min(620px, 84cqmin); height: min(620px, 84cqmin); }
  .ow-mark { --ow-wing-h: min(clamp(90px, 19vh, 180px), calc(min(620px, 84cqmin) * .24)); }
  .ow-logo-type { width: min(clamp(160px, 17vw, 280px), calc(min(620px, 84cqmin) * .38)); }
}

/* ---------- PANELS FILLED BY ELEMENTOR ---------- */

/* Elementor sections bring their own padding; the panel only scrolls them */
.ow-panel.ow-panel--elementor { display: block; padding: 0; }
.ow-elementor { min-height: 100%; }

/* ---------- ABOUT (default content) ---------- */

/* two columns so the panel never needs to scroll: in RTL the first column lands on the right */
.ow-panel--about { display: grid; align-content: center; }

.ow-about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 72px);
  align-items: start;
  width: 100%;
  max-width: 1080px;
  margin-inline: auto;
}

.ow-about__col > :first-child { margin-top: 0; }
.ow-about__col > :last-child  { margin-bottom: 0; }

.ow-about h3 { font-size: clamp(21px, 2.5vw, 31px); margin: 0 0 .45em; line-height: 1.45; }
.ow-about h4 { font-size: clamp(16px, 1.8vw, 20px); margin: 0 0 .9em; color: var(--ow-gold-deep); font-weight: 600; }
.ow-about p  { margin: 0 0 .85em; }

@media (max-width: 767px) {
  .ow-about { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------- PROJECTS ----------
   A row of circles picks the project; below it the story sits on the
   reading side and the tall artwork fills the other side, edge to edge.
   (Layout after the reference Mohi chose, mirrored for RTL.) */

.ow-panel--work { padding: 0; }

.ow-work {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

/* --- picker --- */

.ow-work__picker {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(64px, 1fr);
  justify-items: center;
  align-items: center;
  gap: 16px;
  padding: 20px var(--ow-shell-pad);
  background: rgba(10, 13, 16, .55);       /* Obsidian 900 — a shade under the stage */
  border-bottom: 1px solid var(--ow-border);
}

.ow-work__pick {
  position: relative;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
}

.ow-work__pick img,
.ow-work__initial {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.ow-work__initial {
  display: grid;
  place-items: center;
  background: var(--ow-surface);
  color: var(--ow-text);
  font-size: 24px;
  font-weight: 700;
}

/* only the chosen project is in full colour, inside a gold ring */
.ow-work__pick[role="tab"] {
  opacity: .5;
  filter: grayscale(.5);
  transition: opacity .25s, filter .25s, box-shadow .25s;
}
.ow-work__pick[role="tab"]:hover { opacity: .85; filter: none; }
.ow-work__pick[aria-selected="true"] {
  opacity: 1;
  filter: none;
  box-shadow: 0 0 0 3px var(--ow-box), 0 0 0 5px var(--ow-gold-deep);
}

.ow-work__pick--soon {
  background: var(--ow-surface);
  opacity: .45;
  overflow: hidden;
}
.ow-work__pick--soon img { width: 80%; height: auto; border-radius: 0; opacity: .35; object-fit: contain; }
.ow-work__pick--soon span {
  position: absolute;
  color: var(--ow-text);
  font-size: 11px;
  font-weight: 800;
}

/* --- one project --- */

.ow-work__item {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 34%);
  min-height: 0;
  animation: owWorkIn .45s var(--ow-ease);
}
.ow-work__item[hidden] { display: none; }

@keyframes owWorkIn { from { opacity: 0; transform: translateY(8px); } }
@keyframes owWorkFade { from { opacity: 0; } }

.ow-work__info { display: flex; flex-direction: column; min-width: 0; }

/* sections divided by hairlines, as in the reference */
.ow-work__block { padding: clamp(20px, 2.6vw, 34px) var(--ow-shell-pad); }
.ow-work__block + .ow-work__block { border-top: 1px solid var(--ow-border); }

.ow-work__title {
  margin: 0;
  font-size: clamp(30px, 4.4vw, 56px);
  font-weight: 800;
  line-height: 1.2;
}
.ow-work__logo { margin: 0; line-height: 0; }
.ow-work__logo img { width: auto; height: clamp(48px, 7vw, 84px); }

.ow-work__lead {
  margin: .9em 0 0;
  max-width: 60ch;
  color: var(--ow-text);
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.9;
}

.ow-work__desc {
  margin-top: .8em;
  max-width: 80ch;
  color: var(--ow-text-dim);
  font-size: 15px;
  line-height: 1.9;
}
.ow-work__desc p:last-child { margin-bottom: 0; }

.ow-work__label {
  margin: 0 0 16px;
  color: var(--ow-text);
  font-size: 13px;
  font-weight: 800;
}

.ow-work__details {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 18px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ow-work__details li { line-height: 1.5; }
.ow-work__details strong { display: block; color: var(--ow-text); font-size: 15px; font-weight: 700; }
.ow-work__details span { color: var(--ow-text-muted); font-size: 13px; }

.ow-actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* tall artwork, edge to edge on its side of the stage */
.ow-work__art {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-inline-start: 1px solid var(--ow-border);
  background: var(--ow-surface);
}
.ow-work__art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

@media (max-width: 900px) {
  .ow-work__picker {
    grid-auto-columns: 56px;
    justify-content: start;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .ow-work__pick { width: 52px; height: 52px; }

  .ow-work__item { grid-template-columns: 1fr; }
  .ow-work__art {
    order: -1;                             /* artwork first on phones */
    height: 34vh;
    border-inline-start: 0;
    border-bottom: 1px solid var(--ow-border);
  }
}

/* desktop: the whole project fits the stage without scrolling.
   Sizes follow the stage height (vh), so a 768px laptop gets a tighter
   version of the same layout. The panel can still scroll as a last resort. */
@media (min-width: 901px) {
  /* fade only: the 8px slide would flash a scrollbar when the content fills the stage exactly */
  .ow-work__item { animation-name: owWorkFade; }

  .ow-work__picker { padding-block: clamp(8px, 1.6vh, 16px); }
  .ow-work__pick { width: clamp(42px, 6vh, 60px); height: clamp(42px, 6vh, 60px); }

  .ow-work__info { min-height: 0; }
  .ow-work__block { padding-block: clamp(12px, 2.6vh, 28px); }
  .ow-work__block:first-child { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: center; }

  .ow-work__title { font-size: clamp(28px, min(4.2vw, 6.4vh), 56px); line-height: 1.15; }
  .ow-work__logo img { height: clamp(40px, 7vh, 84px); }
  .ow-work__lead { margin-top: .6em; line-height: 1.7; }
  .ow-work__desc {
    margin-top: .5em;
    line-height: 1.8;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
  }
  .ow-work__desc p { margin: 0; }

  .ow-work__label { margin-bottom: clamp(8px, 1.4vh, 14px); }
  .ow-work__details { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px 20px; }
}

@media (min-width: 901px) and (max-height: 760px) {
  .ow-work__desc { -webkit-line-clamp: 2; }
  .ow-work__lead { font-size: 15px; }
}
@media (min-width: 901px) and (max-height: 660px) {
  .ow-work__desc { display: none; }        /* the subtitle already says it in one line */
  .ow-work__details { gap: 8px 16px; }
  .ow-work__block { padding-block: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .ow-work__item { animation: none; }
}

/* ---------- PROJECTS: THE ORBIT (1.8.0, Mohi's design) ----------
   Two screens stacked inside the panel. On touch screens the panel scrolls
   between them; with a mouse only the «click» buttons do, and the wheel turns
   pages (ow-shell.js, 1.8.2):
   1. .ow-orbit       the obsidian ball and one sphere per palette family,
                      moved and thrown around by ow-orbit.js (decoration)
   2. .ow-orbit-list  one sphere per published project: the project's card
   Every sphere is an .ow-orb. A palette family sets four shades (--o-*);
   the background layers turn them into a lit ball with an uneven surface. */

.ow-panel--work {
  container-type: size;                    /* the screens size themselves with cqh */
  scroll-snap-type: y proximity;
  scrollbar-width: none;                   /* the «scroll» buttons say there is more */
}
.ow-panel--work::-webkit-scrollbar { display: none; }

/* one sky for both screens: a tall, non-repeating star field (make-starfield.ps1, 1.8.2),
   so the projects below read as the same sky going on. Drawn at its own size on
   phones and small screens (never stretched), wider screens scale it up. */
.ow-orbit-panel {
  background: var(--ow-box) url("../images/stars-tall.png") center top / max(100%, 1200px) auto no-repeat;
}
.ow-orbit,
.ow-orbit-list {
  position: relative;
  scroll-snap-align: start;
  background: radial-gradient(ellipse 58% 52% at 50% 48%, rgba(47, 67, 86, .6), rgba(47, 67, 86, .16) 58%, rgba(47, 67, 86, 0) 82%);   /* Slate Blue 800 glow */
}

.ow-orbit {
  height: calc(100vh - var(--ow-bar-h) * 2 - 24px);      /* fallback: no container units */
  height: 100cqh;
  overflow: hidden;
  isolation: isolate;                      /* the spheres and the ball share one stacking order */
}

/* far half behind the ball, near half over it (the ball is 2, near spheres 3 and later in the markup).
   Faint: Mohi wanted them back (1.8.2), but quieter than in 1.8.0 */
.ow-orbit__rings {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.ow-orbit__rings--front { z-index: 3; }
.ow-orbit__rings path {
  fill: none;
  stroke: #65727E;                         /* Obsidian 300 */
  stroke-opacity: .26;
  stroke-width: 1;
}

/* --- the sphere --- */

.ow-orb {
  --d: 48px;
  --img: none;
  --o-inner:
    inset calc(var(--d) * -.09) calc(var(--d) * -.11) calc(var(--d) * .24) rgba(10, 13, 16, .55),   /* night side */
    inset calc(var(--d) * .03) calc(var(--d) * .04) calc(var(--d) * .08) rgba(248, 249, 250, .16);   /* lit rim */
  display: block;
  width: var(--d);
  height: var(--d);
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 26%, rgba(248, 249, 250, .3), rgba(248, 249, 250, 0) 30%),                                         /* highlight */
    radial-gradient(circle at 36% 32%, rgba(10, 13, 16, 0) 44%, rgba(10, 13, 16, .4) 80%, rgba(10, 13, 16, .72) 100%),                 /* one light for every planet */
    var(--img) center / cover no-repeat,                                                                                              /* the planet itself */
    radial-gradient(circle at 36% 32%, var(--o-hi) 0%, var(--o-base) 36%, var(--o-mid) 64%, var(--o-dark) 100%);                         /* colour (and fallback) */
  background-blend-mode: screen, normal, normal, normal;
  box-shadow: var(--o-inner), 0 0 calc(var(--d) * .45) var(--o-glow);
}

/* one family of the palette each (vault: «Brand Palette») — 200 · 400 · 600 · 900.
   The planets (1.8.1, Mohi's references, openclipart / public domain) are
   gradient-mapped onto the same family: each pixel's brightness picks a shade
   900 → 50, so the detail stays and the colours are ours. Made by orbs.ps1. */
.ow-orb--obsidian { --o-hi: #8A959E; --o-base: #2E3843; --o-mid: #1A2027; --o-dark: #0A0D10; --o-glow: rgba(122, 92, 142, .3);  --img: url("../images/orbs/obsidian.jpg"); }  /* volcanic glass, gold and silver veins (make-obsidian-texture.ps1) */
.ow-orb--gold     { --o-hi: #E9DFA0; --o-base: #CAA93D; --o-mid: #A98139; --o-dark: #403018; --o-glow: rgba(202, 169, 61, .26);  --img: url("../images/orbs/gold.jpg"); }     /* Venus */
.ow-orb--slate    { --o-hi: #C1D1DF; --o-base: #7E9CBA; --o-mid: #4E6D8B; --o-dark: #202E3C; --o-glow: rgba(126, 156, 186, .24); --img: url("../images/orbs/slate.jpg"); }    /* Jupiter */
.ow-orb--bronze   { --o-hi: #E5C5A8; --o-base: #BA8143; --o-mid: #91623D; --o-dark: #38231B; --o-glow: rgba(186, 129, 67, .24);  --img: url("../images/orbs/bronze.jpg"); }   /* Jupiter, illustrated */
.ow-orb--moss     { --o-hi: #BDD2C8; --o-base: #7AA691; --o-mid: #4D7867; --o-dark: #20342E; --o-glow: rgba(122, 166, 145, .24); --img: url("../images/orbs/moss.jpg"); }     /* Europa */
.ow-orb--plum     { --o-hi: #D7C6DD; --o-base: #8B6DA0; --o-mid: #654C76; --o-dark: #2A2133; --o-glow: rgba(139, 109, 160, .28); --img: url("../images/orbs/plum.jpg"); }     /* Jupiter, turned over */
.ow-orb--silver   { --o-hi: #F1F3F4; --o-base: #B3BAC0; --o-mid: #78818A; --o-dark: #252C32; --o-glow: rgba(179, 186, 192, .22); --img: url("../images/orbs/silver.jpg"); }   /* the Moon */
.ow-orb--burgundy { --o-hi: #D1B0B8; --o-base: #A36D7A; --o-mid: #743D4D; --o-dark: #311A22; --o-glow: rgba(163, 109, 122, .28); --img: url("../images/orbs/burgundy.jpg"); } /* Mars */

/* --- the obsidian ball in the middle: polished glass with the mark --- */

.ow-orbit__core {
  position: absolute;
  left: 50%;
  top: 48%;
  z-index: 2;
  translate: -50% -50%;
  pointer-events: none;
}
.ow-orbit__ball {
  --d: var(--ow-core-d, 150px);
  display: grid;
  place-items: center;
  box-shadow:
    var(--o-inner),
    0 0 0 1px rgba(202, 169, 61, .22),                    /* thin gold rim */
    0 0 calc(var(--d) * .5) rgba(122, 92, 142, .32),       /* plum aura */
    0 0 calc(var(--d) * 1.1) rgba(47, 67, 86, .5);         /* slate halo */
}
.ow-orbit__ball img {
  width: 64%;
  height: auto;
  filter: drop-shadow(0 calc(var(--d) * .03) calc(var(--d) * .06) rgba(10, 13, 16, .7));
}

/* --- the orbiting spheres (positions come from ow-orbit.js) --- */

.ow-orbit__orb {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  cursor: grab;
  touch-action: none;                      /* a finger drags the sphere, not the page */
  will-change: transform;
}
.ow-orbit:not(.is-ready) .ow-orbit__orb { visibility: hidden; }
.ow-orbit__orb.is-held {
  cursor: grabbing;
  box-shadow: var(--o-inner), 0 0 calc(var(--d) * .8) var(--o-glow), 0 0 0 1px rgba(202, 169, 61, .45);
}
.ow-orbit.is-dragging { cursor: grabbing; }

/* --- «scroll» hints between the two screens --- */

.ow-orbit__hint {
  position: absolute;
  left: 50%;
  z-index: 5;
  translate: -50% 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 8px 16px;
  border: 0;
  background: none;
  color: var(--ow-text-dim);
  font: inherit;
  font-size: 15px;
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color .25s;
}
.ow-orbit__hint:hover,
.ow-orbit__hint:focus-visible { color: var(--ow-gold); }
.ow-orbit__hint-click { display: none; }
@media (hover: hover) and (pointer: fine) {          /* a mouse: say «click», not «scroll» */
  .ow-orbit__hint-touch { display: none; }
  .ow-orbit__hint-click { display: inline; }
}
.ow-orbit__hint--down { bottom: clamp(10px, 3cqh, 26px); }
.ow-orbit__hint--up   { top: clamp(10px, 3cqh, 26px); }
.ow-orbit__hint svg   { animation: owHintDown 2.2s ease-in-out infinite; }
.ow-orbit__hint--up svg { rotate: 180deg; animation-name: owHintUp; }
@keyframes owHintDown { 50% { translate: 0 3px; } }
@keyframes owHintUp   { 50% { translate: 0 -3px; } }

/* --- screen 2: the projects, one sphere each --- */

.ow-orbit-list {
  min-height: calc(100vh - var(--ow-bar-h) * 2 - 24px);
  min-height: 100cqh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(64px, 12cqh, 110px) var(--ow-shell-pad) clamp(40px, 8cqh, 80px);
}

.ow-planets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(28px, 5vw, 72px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ow-planets li { animation: owPlanetFloat 4.6s ease-in-out infinite; animation-delay: calc(var(--ow-i, 0) * -1.3s); }
@keyframes owPlanetFloat { 50% { translate: 0 -5px; } }

.ow-planet {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 250px;
  max-width: 100%;
  color: inherit;
  text-align: center;
  text-decoration: none;
}
.ow-planet__orb {
  --d: clamp(96px, 17cqh, 136px);
  display: grid;
  place-items: center;
  margin-bottom: 10px;
  transition: translate .45s var(--ow-ease), box-shadow .45s var(--ow-ease);
}
.ow-planet__logo { width: 58%; height: auto; filter: drop-shadow(0 2px 6px rgba(10, 13, 16, .5)); }
.ow-planet__name { color: var(--ow-text); font-size: 19px; font-weight: 700; line-height: 1.5; transition: color .25s; }
.ow-planet__desc { max-width: 28ch; color: var(--ow-text-muted); font-size: 14px; line-height: 1.85; }

.ow-planet:hover .ow-planet__orb,
.ow-planet:focus-visible .ow-planet__orb {
  translate: 0 -6px;
  box-shadow: var(--o-inner), 0 0 calc(var(--d) * .8) var(--o-glow), 0 0 0 1px rgba(202, 169, 61, .45);
}
.ow-planet:hover .ow-planet__name,
.ow-planet:focus-visible .ow-planet__name { color: var(--ow-gold); }
.ow-planet:focus-visible { outline: none; }

/* --- entrance (first visit only, like the other panels) --- */

@keyframes owOrbitFade { from { opacity: 0; filter: blur(6px); } }
.ow-panel.is-active .ow-orbit__rings,
.ow-panel.is-active .ow-orbit__core { animation: owOrbitFade 1s var(--ow-ease-enter) .2s backwards; }
.ow-panel.is-active .ow-orbit__orb  { animation: owOrbitFade .9s var(--ow-ease-enter) backwards; animation-delay: calc(.5s + var(--ow-i, 0) * .1s); }
.ow-panel.ow-seen .ow-orbit__rings,
.ow-panel.ow-seen .ow-orbit__core,
.ow-panel.ow-seen .ow-orbit__orb { animation: none; }

@media (max-width: 767px) {
  .ow-planet { width: 200px; }
  .ow-orbit__hint { font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .ow-orbit__hint svg,
  .ow-planets li,
  .ow-panel.is-active .ow-orbit__rings,
  .ow-panel.is-active .ow-orbit__core,
  .ow-panel.is-active .ow-orbit__orb { animation: none; }
  .ow-orbit__orb { cursor: default; }
}

/* ---------- CONTACT ---------- */

.ow-panel--contact { padding: 0; overflow: hidden; }

.ow-contact {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 4vh, 44px);
  padding: clamp(20px, 4vw, 56px);
  text-align: center;
  overflow: hidden;
}

.ow-contact h2,
.ow-contact .ow-reveal,
.ow-contact .ow-social { position: relative; z-index: 1; }

.ow-contact h2 { font-size: clamp(24px, 3.6vw, 42px); margin: 0; }

/* twinkling stars (placeholder backdrop, Mohi 1405/07/21). The SVG animates itself
   and carries its own #12161B fill, the same as the stage. */
.ow-contact {
  background: var(--ow-box) url("../images/twinkling-stars.svg") center / cover no-repeat;
}

/* --- About backdrop: faint grid, corner rings, crosshair marks
       (moved here from the contact panel in 1.5.0) --- */

.ow-backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;              /* the rings hang off the corners; never let them scroll the panel */
  pointer-events: none;
}
.ow-panel--about > .ow-about { position: relative; z-index: 1; }

.ow-backdrop__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right,  rgba(46, 56, 67, .5) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(46, 56, 67, .5) 1px, transparent 1px);
  background-size: 48px 48px;
  pointer-events: none;
}

.ow-rings {
  position: absolute;
  width: min(44vmin, 360px);
  height: min(44vmin, 360px);
  color: var(--ow-border);
  pointer-events: none;
}
.ow-rings--a { top: -7%;    left: -5%; }     /* physical sides: the panel is RTL */
.ow-rings--b { bottom: -9%; right: -5%; }

.ow-plus {
  position: absolute;
  width: 15px;
  height: 15px;
  color: var(--ow-text-muted);
  opacity: .55;
  pointer-events: none;
}
.ow-plus--tr { top: 9%;     right: 9%; }
.ow-plus--bl { bottom: 13%; left: 10%; }

/* --- drag to reveal the address --- */

.ow-reveal { display: flex; justify-content: center; }

.ow-reveal .ow-reveal__track {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(430px, 80vw);
  height: 74px;
  padding-inline: clamp(72px, 20%, 88px);
  border: 1px solid var(--ow-gold-deep);
  border-radius: 999px;
  background: rgba(18, 22, 27, .78);
  box-shadow:
    0 0 26px rgba(200, 160, 77, .16),
    inset 0 0 20px rgba(200, 160, 77, .05);
  color: var(--ow-text);
  font-family: inherit;
  font-size: clamp(15px, 1.5vw, 17px);
  line-height: 1;
  text-decoration: none;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y;             /* vertical scroll stays with the panel */
  direction: ltr;                  /* the knob starts on the physical left */
  transition: border-color .25s, box-shadow .25s;
}

.ow-reveal .ow-reveal__track:hover  { border-color: var(--ow-gold); box-shadow: 0 0 30px rgba(200, 160, 77, .26), inset 0 0 20px rgba(200, 160, 77, .06); }
.ow-reveal .ow-reveal__track:active { cursor: grabbing; }

.ow-reveal__label {
  direction: rtl;
  pointer-events: none;
  white-space: nowrap;
}

.ow-reveal__knob {
  position: absolute;
  top: 50%;
  left: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  margin-top: -31px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #D9C66C, #B07A4A);   /* Warm Gold 300 → Soft Bronze 500 */
  color: #12161B;
  box-shadow: 0 2px 14px rgba(10, 13, 16, .45);
  pointer-events: none;
}

.ow-reveal__knob svg { display: block; }
.ow-reveal .ow-reveal__check { display: none; }

/* completed */
.ow-reveal[data-state="done"] .ow-reveal__arrow { display: none; }
.ow-reveal[data-state="done"] .ow-reveal__check { display: block; }
.ow-reveal[data-state="done"] .ow-reveal__track { cursor: pointer; }

/* a small nudge so the control reads as draggable */
@keyframes owNudge { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(4px); } }
.ow-reveal[data-state="idle"] .ow-reveal__arrow { animation: owNudge 1.9s ease-in-out infinite; }

.ow-reveal__fallback { display: block; margin-top: 10px; font-size: 14px; }

/* --- social --- */

.ow-social {
  display: flex;
  gap: 26px;
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 15px;
  direction: ltr;                  /* instagram first, as in the mock (Dribbble removed in 1.8.0) */
}
/* Borna licence badge (fontiran.com): bottom left, small and quiet; full colour on hover (Mohi, 1405/07/21) */
.ow-contact .ow-font-badge {
  position: absolute;
  left: clamp(14px, 2.4vw, 28px);          /* physical: bottom left in both languages */
  bottom: clamp(14px, 2.4vw, 28px);
  z-index: 1;
  line-height: 0;
  --ow-i: 5;                               /* the contact entrance (below) brings it in last */
}
/* the dimming sits on the img: the link itself runs the entrance animation, whose blur would fight a filter here */
.ow-contact .ow-font-badge img {
  display: block;
  width: 48px;
  height: 48px;
  opacity: .45;
  filter: grayscale(1);
  transition: opacity .25s, filter .25s;
}
.ow-contact .ow-font-badge:hover img,
.ow-contact .ow-font-badge:focus-visible img { opacity: 1; filter: none; }

.ow-social a { color: var(--ow-gold-deep); transition: color .25s; }
.ow-social a:hover { color: var(--ow-gold); }

@media (max-width: 767px) {
  /* same selector weight as the desktop rule, or these never apply */
  .ow-reveal .ow-reveal__track { height: 62px; padding-inline: 62px; font-size: 14px; }
  .ow-reveal .ow-reveal__knob  { width: 52px; height: 52px; margin-top: -26px; }
  .ow-rings         { width: min(60vmin, 280px); height: min(60vmin, 280px); }
  .ow-plus--tr, .ow-plus--bl { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ow-reveal[data-state="idle"] .ow-reveal__arrow { animation: none; }
}

/* ---------- TEXT ENTRANCE: ABOUT · PROJECTS · CONTACT (Mohi, 1405/07/21) ----------
   Each time a panel becomes .is-active its text rises in, one line after another,
   while the panel itself is still sliding (--ow-swap .6s). The animations start
   again on every visit because the selector stops and starts matching.
   "backwards" fill: hidden until its turn, no leftover transform afterwards. */

@keyframes owTextIn   { from { opacity: 0; transform: translateY(18px); filter: blur(6px); } }
@keyframes owTextFade { from { opacity: 0; filter: blur(6px); } }

.ow-panel.is-active .ow-contact > * {
  animation: owTextIn .7s var(--ow-ease-enter) backwards;
  animation-delay: calc(.18s + var(--ow-i, 0) * .09s);
}

/* contact: headline, slider, links */
.ow-contact > :nth-child(2) { --ow-i: 2; }
.ow-contact > :nth-child(3) { --ow-i: 4; }

/* projects: slower (Mohi, 1405/07/21). First the frame arrives, one piece at a
   time — circles, story blocks, artwork — then the text writes itself in (below). */
.ow-panel.is-active .ow-work__picker,
.ow-panel.is-active .ow-work__block,
.ow-panel.is-active .ow-work__art {
  animation: owTextIn 1s var(--ow-ease-enter) backwards;
  animation-delay: calc(.2s + var(--ow-i, 0) * .15s);
}
.ow-work__block:nth-child(1) { --ow-i: 1; }
.ow-work__block:nth-child(2) { --ow-i: 2; }
.ow-work__block:nth-child(3) { --ow-i: 3; }
.ow-panel.is-active .ow-work__art { animation-name: owTextFade; --ow-i: 1; }

/* desktop projects fit the stage exactly; a rising block would flash a scrollbar */
@media (min-width: 901px) {
  .ow-panel.is-active .ow-work__block { animation-name: owTextFade; }
}

/* --- word by word: About (all within 4s), project text (after its frame,
   done by 4s) and the case study (Mohi, 1405/07/21) ---
   ow-shell.js wraps each word in .ow-w with its index (--ow-wi) and sets
   --ow-word-start / --ow-word-step on the box around it. Without JS the text simply shows. */
/* .ow-w must stay inline: an inline-block word is an atomic box to the bidi
   algorithm, so in the RTL page "Obsidian Gaming" read "Gaming Obsidian".
   transform does not apply to inline boxes, so the rise uses position + top. */
@keyframes owWordIn { from { opacity: 0; top: .35em; filter: blur(4px); } }
.ow-w { position: relative; top: 0; }
.ow-panel.is-active .ow-w,
.ow-case.is-open .ow-w-on .ow-w {
  animation: owWordIn .4s var(--ow-ease-enter) backwards;
  animation-delay: calc(var(--ow-word-start, .15s) + var(--ow-wi, 0) * var(--ow-word-step, 0s));
}
/* case study blocks below the fold wait until they are scrolled to (ow-case.js) */
.ow-case .ow-w-wait .ow-w { opacity: 0; }

/* only the first visit animates (Mohi, 1405/07/21): ow-shell.js marks a panel
   .ow-seen when it is left, ow-case.js a case study it has shown before */
.ow-panel.ow-seen .ow-w,
.ow-panel.ow-seen .ow-work__picker,
.ow-panel.ow-seen .ow-work__block,
.ow-panel.ow-seen .ow-work__art,
.ow-panel.ow-seen .ow-contact > *,
.ow-case.is-open .ow-seen .ow-w { animation: none; }
.ow-case .ow-seen .ow-w-wait .ow-w { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .ow-panel.is-active .ow-w,
  .ow-case.is-open .ow-w-on .ow-w,
  .ow-panel.is-active .ow-work__picker,
  .ow-panel.is-active .ow-work__block,
  .ow-panel.is-active .ow-work__art,
  .ow-panel.is-active .ow-contact > * { animation: none; }
  .ow-case .ow-w-wait .ow-w { opacity: 1; }
}

/* ---------- CASE STUDY INSIDE THE STAGE (ow-case.js) ----------
   The project page's <article> shown over the panels, between the bars,
   so the music keeps playing. project.css styles the article itself. */

.ow-case {
  position: absolute;
  inset: 0;
  z-index: 6;                              /* over the panels and the dots */
  display: flex;
  flex-direction: column;
  background: var(--ow-box);
  opacity: 0;
  visibility: hidden;
  transform: translateY(18px);
  transition:
    opacity    .5s var(--ow-ease-enter),
    transform  .5s var(--ow-ease-enter),
    visibility 0s linear .5s;
}
.ow-case.is-open { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }

.ow-case__bar {
  flex: none;
  display: flex;
  align-items: center;
  padding: 12px clamp(16px, 3vw, 32px);
  border-bottom: 1px solid var(--ow-border);
}
.ow-case__close {
  height: 40px;
  padding: 0 18px;
  border: 1px solid var(--ow-border);
  border-radius: 999px;
  background: transparent;
  color: var(--ow-text-muted);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  transition: border-color .25s, color .25s;
}
.ow-case__close::before { content: "→"; margin-inline-end: 8px; }     /* RTL: back points right */
html.ow-en .ow-case__close::before { content: "←"; }
.ow-case__close:hover { border-color: var(--ow-gold-deep); color: var(--ow-text); }

.ow-case__scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--ow-border) transparent;
}

/* live demo: a whole site in a frame, so it takes the whole window (1.6.2,
   Mohi: inside the stage it no longer felt like a demo). Back + music float
   over it at the bottom right; the demo's own badge sits bottom left. */
.ow-case.is-demo {
  position: fixed;                         /* .ow-stage has no transform, so this escapes it */
  inset: 0;
  z-index: 100;
  background: #444;                        /* the demo's own page colour while it loads (the demo's palette, not the site's) */
}
.ow-case.is-demo .ow-case__scroll { overflow: hidden; }
.ow-case__frame { display: block; width: 100%; height: 100%; border: 0; background: #444; }

.ow-case.is-demo .ow-case__bar {
  position: absolute;
  z-index: 1;
  bottom: 16px;
  right: 16px;                             /* physical: the demo's badge is bottom left */
  gap: 8px;
  padding: 0;
  border: 0;
}
.ow-case.is-demo .ow-case__close,
.ow-case__sound {
  height: 42px;
  border: 1px solid rgba(248, 249, 250, .2);
  border-radius: 999px;
  background: rgba(18, 22, 27, .82);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--ow-text);
  box-shadow: 0 6px 18px rgba(10, 13, 16, .35);
}
.ow-case__sound {
  display: none;
  width: 42px;
  padding: 0;
  place-items: center;
  cursor: pointer;
}
.ow-case.is-demo .ow-case__sound { display: grid; }
.ow-case__sound .ow-sound__on                         { display: none; }
.ow-case__sound[aria-pressed="true"] .ow-sound__on    { display: inline; }
.ow-case__sound[aria-pressed="true"] .ow-sound__off   { display: none; }
.ow-case__ext { display: none; }

.ow-shell.is-case .ow-dots { visibility: hidden; }
.ow-shell.is-case-loading { cursor: progress; }

/* ---------- ENGLISH (html.ow-en, see inc/lang.php) ---------- */

html.ow-en .ow-reveal__label { direction: ltr; }
