/* =====================================================================
   NAVIDIX — lesson diagrams.

   Three figures the camera lesson needs and could not have as prose: the
   vertical axis, the seven shot sizes, and the six families of movement.
   Each is one <svg> stage plus a row of controls, and each is driven by
   the same three lines of JS — pick a control, the stage animates to that
   state, the caption underneath says what the state means.

   The stage is the diagram. The controls are ordinary buttons, the
   caption is ordinary text, and the state lives in one data attribute on
   the figure — so the whole thing is inspectable, keyboard-operable and
   readable by a screen reader without a single ARIA workaround.

   Loaded only by the lessons that carry a figure, not by the whole
   training section: a lesson with no diagram should not pay for one.
   Palette and motion rules are nvx-training.css's — this file adds no
   colour and animates nothing but transform, opacity and stroke.
   ===================================================================== */

.nvx-dg{
  position:relative; margin:26px 0 30px;
  border:1px solid rgba(150,175,215,.17); border-radius:6px;
  background:
    radial-gradient(120% 150% at 88% 0%, rgba(229,32,42,.07), transparent 60%),
    linear-gradient(158deg, rgba(32,38,48,.55) 0%, rgba(12,15,19,.72) 60%, rgba(10,12,16,.78) 100%);
  box-shadow:inset 0 1px 0 rgba(226,238,255,.07), 0 24px 48px -34px rgba(0,0,0,.95);
  padding:clamp(16px,2.6vw,24px);
  overflow:hidden;
}

/* ---- the stage ---- */
.nvx-dg__stage{
  display:block; width:100%; height:auto; overflow:hidden;
  background:#080B0E; border:1px solid #1B1F26; border-radius:5px;
}
/* The page is rtl and svg text inherits it, so an x is read as the run's
   right edge and a latin label walks off the left of the stage. These
   labels are always latin; say so once, here. */
.nvx-dg__stage text{
  font-family:ui-monospace,Menlo,Vazirmatn,monospace; font-size:9px;
  fill:#7B838D; letter-spacing:.06em;
  direction:ltr; text-anchor:start;
}

/* everything that moves does so on the same curve, so two diagrams on
   one page read as one instrument rather than two widgets */
.nvx-dg [data-move]{ transition:transform .62s cubic-bezier(.16,1,.3,1); }
.nvx-dg [data-fade]{ transition:opacity .45s cubic-bezier(.16,1,.3,1); }

.nvx-dg .grid line{ stroke:#171B22; stroke-width:1; }
.nvx-dg .axis{ stroke:rgba(150,175,215,.22); stroke-width:1; stroke-dasharray:3 4; }
/* Bright enough that the crop figure has something to reveal. On a
   near-black stage a subject at #2A313B and a veil over it are the same
   colour, and the whole point of that figure is the difference. */
.nvx-dg .subject{ fill:#3E4854; stroke:#646F7E; stroke-width:1; }
.nvx-dg .subject-head{ fill:#4B5663; stroke:#727E8D; stroke-width:1; }
.nvx-dg .ground{ stroke:#333B45; stroke-width:1.5; }
.nvx-dg .prop{ fill:#20262E; stroke:#39424E; stroke-width:1; }

/* the camera body and the cone of what it sees */
.nvx-dg .cam{ fill:#E5202A; }
.nvx-dg .cam-body{ fill:#161A20; stroke:#E5202A; stroke-width:1.5; }
.nvx-dg .cone{ fill:rgba(229,32,42,.13); stroke:rgba(229,32,42,.5); stroke-width:1; }
.nvx-dg .arc{ fill:none; stroke:rgba(150,175,215,.2); stroke-width:1; stroke-dasharray:2 5; }
.nvx-dg .limb{ fill:none; stroke:#646F7E; stroke-linecap:round; }

/* The crop and the hole it cuts in the veil are the same rectangle drawn
   twice, so they share the transition and nothing else. They must not
   share a class: the visible one is fill:none, and a mask rect that
   inherits fill:none stops being a hole — the veil then covers the whole
   stage evenly and the figure has nothing to show. */
.nvx-dg .crop, .nvx-dg .crop-hole{
  transition:x .62s cubic-bezier(.16,1,.3,1), y .62s cubic-bezier(.16,1,.3,1),
             width .62s cubic-bezier(.16,1,.3,1), height .62s cubic-bezier(.16,1,.3,1);
}
.nvx-dg .crop{ fill:none; stroke:#E5202A; stroke-width:2; }
.nvx-dg .crop-hole{ fill:#000; stroke:none; }

/* ---- the lit subject ----
   Light is white here and the camera is ember, which is the whole legend:
   red is where the frame is taken from, white is where the light comes
   from. No third colour is introduced, so nothing has to be learned. */
.nvx-dg .wall{ fill:#0E1218; }
.nvx-dg .face{ fill:none; stroke:rgba(226,238,255,.3); stroke-width:1.2; stroke-linecap:round; }
.nvx-dg .shade{ fill:#04060A; }
.nvx-dg .rim{ fill:none; stroke:#EAF1FA; stroke-width:2.4; stroke-linecap:round; }
.nvx-dg .lamp{ fill:#EAF1FA; }
.nvx-dg .lamp-ray{ fill:none; stroke:#EAF1FA; stroke-width:1.5; stroke-linecap:round; }
.nvx-dg .lamp-cone{ fill:rgba(233,244,255,.09); stroke:rgba(233,244,255,.32); stroke-width:1; }
.nvx-dg .pip{ fill:#EAF1FA; }

/* the frame's own composition marks */
.nvx-dg .third{ stroke:rgba(233,244,255,.32); stroke-width:1; stroke-dasharray:4 5; }
.nvx-dg .dot{ fill:#E5202A; }
.nvx-dg .lead{ fill:none; stroke:rgba(229,32,42,.8); stroke-width:1.4; stroke-linecap:round; }
.nvx-dg .fore{ fill:#090C11; stroke:#39424E; stroke-width:1.2; }

/* a value stamped on the stage rather than written under it — the number
   is the state, so it belongs where the state is */
.nvx-dg__stage text.stamp{ fill:#E5202A; letter-spacing:.14em; }
.nvx-dg__stage text.big{ font-size:16px; }

/* ---- the production line ---- */
.nvx-dg .rail{ stroke:#262A31; stroke-width:2; }
.nvx-dg .rail-live{
  stroke:#E5202A; stroke-width:2;
  transition:x2 .62s cubic-bezier(.16,1,.3,1);
}
.nvx-dg .pin{ fill:#0B0E14; stroke:#3A424E; stroke-width:1.5; }
.nvx-dg .pin-halo{ fill:rgba(229,32,42,.13); }
.nvx-dg .pin-on{ fill:none; stroke:rgba(229,32,42,.75); stroke-width:1.5; }
.nvx-dg .pin-core{ fill:#E5202A; }

/* ---- the beat track ---- */
.nvx-dg .track{ fill:#0A0D12; stroke:#1B1F26; stroke-width:1; }
.nvx-dg .beat, .nvx-dg .mini-box{
  transition:x .62s cubic-bezier(.16,1,.3,1), width .62s cubic-bezier(.16,1,.3,1);
}
.nvx-dg .beat{ fill:#2A323D; }
.nvx-dg .beat.peak{ fill:rgba(229,32,42,.62); }
/* The only Persian on any stage. It needs the page's own face — no mono
   family carries the script — and it needs the rtl the stage's latin
   rule switches off. */
.nvx-dg__stage text.fa{
  font-family:"Vazirmatn","IRANSans",Tahoma,sans-serif; font-size:12px;
  fill:#D7DEE7; direction:rtl; text-anchor:middle; letter-spacing:normal;
}
.nvx-dg__stage text.mid{ text-anchor:middle; fill:#8C939B; }

/* ---- the four shots ---- */
.nvx-dg .mini-box{ fill:none; stroke:#2A313B; stroke-width:1; }
.nvx-dg .mini-box.is-on{ stroke:#E5202A; stroke-width:2; }
.nvx-dg__stage text.mini-lab{ fill:#5C636C; }
.nvx-dg__stage text.mini-lab.is-on{ fill:#E5202A; }
.nvx-dg .horizon{ stroke:#252C35; stroke-width:1; }

/* a prompt is latin, monospaced and left-aligned wherever it appears —
   including inside a readout the rest of which is Persian */
.nvx-dg__read code{
  display:block; margin-top:11px; padding:10px 12px;
  direction:ltr; text-align:left; white-space:pre-wrap;
  font-family:ui-monospace,Menlo,Vazirmatn,monospace; font-size:11.5px; line-height:1.85;
  color:#B9C0C8; background:#080B0E; border:1px solid #1B1F26; border-radius:4px;
}

/* An element that both moves and fades needs both transitions named in
   one declaration: the two rules above set the same property, so the
   later one would otherwise win outright and the other change would
   snap. */
.nvx-dg [data-move][data-fade]{
  transition:transform .62s cubic-bezier(.16,1,.3,1),
             opacity .45s cubic-bezier(.16,1,.3,1);
}

/* ---- controls ---- */
.nvx-dg__ctrls{
  display:flex; flex-wrap:wrap; gap:8px; margin:16px 0 0;
}
.nvx-dg__ctrls button{
  font-family:inherit; font-size:12.5px; line-height:1; cursor:pointer;
  padding:9px 14px; border-radius:100px; color:#B9C0C8;
  background:transparent; border:1px solid #262A31;
  transition:border-color .22s ease, color .22s ease, background .22s ease;
}
.nvx-dg__ctrls button:hover{ border-color:#3a4049; color:#E9EDF2; }
.nvx-dg__ctrls button[aria-pressed="true"]{
  background:rgba(229,32,42,.15); border-color:rgba(229,32,42,.62); color:#fff;
}
.nvx-dg__ctrls button:focus-visible{ outline:1px solid #B9C0C8; outline-offset:2px; }
.nvx-dg__ctrls button .en{
  display:block; margin-top:5px; font-family:ui-monospace,Menlo,Vazirmatn,monospace;
  font-size:10px; color:#6B7280; direction:ltr;
}
.nvx-dg__ctrls button[aria-pressed="true"] .en{ color:rgba(255,255,255,.62); }

/* ---- the readout ---- */
.nvx-dg__read{
  margin:16px 0 0; padding-top:15px; border-top:1px solid #1B1F26;
  font-size:13.5px; line-height:2; color:#8C939B; min-height:3.4em;
}
.nvx-dg__read b{ color:#E4E7EA; font-weight:600; }
.nvx-dg__read .en{
  font-family:ui-monospace,Menlo,Vazirmatn,monospace; font-size:11.5px;
  color:#E5202A; direction:ltr; display:inline-block; margin-inline-start:8px;
}
.nvx-dg__hint{
  margin:12px 0 0; font-size:11.5px; line-height:1.9; color:#5C636C;
}

/* ---- movement: the one figure that loops ----
   A move is a thing that happens over time, so its figure has to run
   rather than settle. It runs only while its own control is selected,
   which means at most one loop per page and none at all until the reader
   has asked for one. */
.nvx-dg__stage .runner{ animation:none; }
.nvx-dg[data-run="pan"]    .runner{ animation:nvxPan    3.4s ease-in-out infinite alternate; }
.nvx-dg[data-run="dolly"]  .runner{ animation:nvxDolly  3.4s ease-in-out infinite alternate; }
.nvx-dg[data-run="truck"]  .runner{ animation:nvxTruck  3.4s ease-in-out infinite alternate; }
.nvx-dg[data-run="arc"]    .runner{ animation:nvxArc    6s   linear      infinite; }
.nvx-dg[data-run="handheld"] .runner{ animation:nvxHand 1.1s ease-in-out infinite; }

@keyframes nvxPan   { from{ transform:rotate(-19deg) } to{ transform:rotate(19deg) } }
@keyframes nvxDolly { from{ transform:translateX(0) scale(1) } to{ transform:translateX(-54px) scale(1.18) } }
/* plan view: lateral is up and down the page, not across it */
@keyframes nvxTruck { from{ transform:translateY(-52px) } to{ transform:translateY(52px) } }
@keyframes nvxArc   { from{ transform:rotate(0deg) } to{ transform:rotate(360deg) } }
@keyframes nvxHand  {
  0%{ transform:translate(0,0) rotate(0deg) }
  25%{ transform:translate(2.5px,-2px) rotate(.8deg) }
  50%{ transform:translate(-2px,1.5px) rotate(-.6deg) }
  75%{ transform:translate(1.5px,2px) rotate(.5deg) }
  100%{ transform:translate(0,0) rotate(0deg) }
}

/* ---- phone ----
   The stage keeps its full behaviour: it is svg, it scales, and the only
   thing animating is a transform on one group. What goes is the panel's
   blur-weight backdrop and the shadow it casts. */
@media (max-width:760px){
  .nvx-dg{ background:#0E1116; box-shadow:none; }
  .nvx-dg__ctrls{ gap:7px; }
  .nvx-dg__ctrls button{ padding:8px 12px; font-size:12px; }
  .nvx-dg__read{ font-size:13px; }
}

@media (prefers-reduced-motion:reduce){
  .nvx-dg [data-move], .nvx-dg [data-fade], .nvx-dg .crop, .nvx-dg .veil{ transition:none; }
  .nvx-dg .runner{ animation:none !important; }
}
