/* C0136 V2 Rotating Explainer Rail.
   Mohamed's rule, approved on Wasla: explanations rotate, they do not stack.
   Six equal-weight cells give the eye nothing to land on, so the rail shows one
   dominant panel at a time on a numbered spine.

   Progressive enhancement: with no JavaScript, or before boot, the panels render
   as the existing hairline grid, byte-for-byte the layout that ships today. The
   rail geometry only applies once the script sets data-rail-ready. */

/* ---------- Rest state: the current hairline grid ------------------------- */

.rail-stage{
  display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--line);border-left:1px solid var(--line);
}
.rail-panel{
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:32px 28px 36px;
}
.rail-n{
  display:block;font-family:var(--mono);font-size:13px;letter-spacing:.04em;
  color:var(--quiet);font-variant-numeric:tabular-nums;
}
.rail-n b,.rail-n i{font:inherit;font-style:normal;font-weight:inherit;letter-spacing:inherit}
.rail-panel h3{
  margin-top:20px;font-size:19px;font-weight:600;letter-spacing:-.012em;
  color:var(--ink);line-height:1.32;
}
.rail-panel p{
  margin-top:10px;font-size:16px;line-height:1.6;color:var(--muted);text-wrap:pretty;
}
.rail-object,.rail-spine{display:none}

/* ---------- Rail state: one panel, one spine ----------------------------- */

.rail[data-rail-ready="true"]{--rail-dwell:3000ms}
.rail[data-rail-ready="true"] .rail-stage{
  display:block;grid-template-columns:none;border:1px solid var(--line);
  border-radius:var(--r-card);background:var(--paper);
  min-height:300px;overflow:hidden;
}
.rail[data-rail-ready="true"] .rail-panel{
  display:none;border:0;padding:0;
}

/* The object well is a full-height architectural block rather than a small tile
   floating in a taller box, so the panel has no empty corner to defend. */
.rail[data-rail-ready="true"] .rail-panel[data-active="true"]{
  display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:0;
  align-items:stretch;padding:0;min-height:300px;
}
.rail[data-rail-ready="true"] .rail-copy{align-self:center;padding:44px 48px}
.rail[data-rail-ready="true"] .rail-object{
  display:flex;align-items:center;justify-content:center;
  border-left:1px solid var(--line);background:var(--ice);color:var(--blue);
}
.rail[data-rail-ready="true"] .rail-object svg{width:156px;height:156px}

/* Contrast of scale: one colossal numeral against tiny quiet metadata. */
.rail[data-rail-ready="true"] .rail-n{
  display:flex;align-items:baseline;gap:8px;color:var(--line-2);
}
.rail[data-rail-ready="true"] .rail-n b{
  font-size:52px;line-height:.9;font-weight:600;letter-spacing:-.04em;color:var(--blue-line);
}
.rail[data-rail-ready="true"] .rail-n i{font-size:13px;color:var(--quiet)}
.rail[data-rail-ready="true"] .rail-panel h3{
  margin-top:18px;font-size:23px;letter-spacing:-.016em;
}
.rail[data-rail-ready="true"] .rail-panel p{
  margin-top:12px;font-size:17px;max-width:46ch;color:var(--body);
}

/* ---------- The numbered spine ------------------------------------------- */

.rail[data-rail-ready="true"] .rail-spine{
  display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;margin-top:30px;
}
.rail-step{
  position:relative;min-height:44px;padding:12px 2px 0;margin:0;
  border:0;border-top:2px solid var(--line);border-radius:0;
  background:transparent;color:var(--quiet);cursor:pointer;text-align:left;
  font-family:inherit;font-size:13px;letter-spacing:.04em;line-height:1.3;
  font-variant-numeric:tabular-nums;
  transition:color var(--t-base) var(--ease),border-top-color var(--t-base) var(--ease);
}
.rail-step::after{
  content:"";position:absolute;left:0;top:-2px;height:2px;width:0;background:var(--blue);
}
.rail-step:hover{color:var(--body);border-top-color:var(--line-2)}
.rail-step:active{color:var(--ink)}
.rail-step:focus-visible{outline:2px solid var(--blue);outline-offset:3px}

/* The live step keeps a GREY track so the sweep has something to fill. Marking
   it blue up front made the bar read as already complete the instant it became
   active, which is the opposite of a story advancing. Selection is carried by
   the ink instead, and by the sweep itself. */
.rail-step[aria-selected="true"]{color:var(--ink)}
/* Once the reader takes manual control there is no sweep to watch, so the rule
   becomes the marker again. */
.rail[data-rail-ready="true"][data-rail-auto="off"] .rail-step[aria-selected="true"]{
  border-top-color:var(--blue);
}
.rail-step-label{
  display:block;margin-top:4px;color:inherit;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Signature moment: the active step fills across its dwell, so the rail shows
   its own clock instead of advancing without warning. Keyboard focus freezes
   the sweep, while pointer use keeps both shared rail instances consistent. */
.rail[data-rail-ready="true"] .rail-step[aria-selected="true"]::after{
  animation:rail-sweep var(--rail-dwell,6000ms) linear forwards;
  animation-play-state:paused;
}
.rail[data-rail-ready="true"][data-rail-playing="true"] .rail-step[aria-selected="true"]::after{
  animation-play-state:running;
}
.rail[data-rail-ready="true"][data-rail-auto="off"] .rail-step[aria-selected="true"]::after{
  animation:none;width:0;
}

/* Steps already played hold a quiet fill so the rail reads as a story bar
   advancing, rather than one lit segment with no sense of progress. */
.rail[data-rail-ready="true"] .rail-step[data-rail-done="true"]::after{
  width:100%;background:var(--blue-line);animation:none;
}

/* ---------- Entrance: the object draws, then the copy rises -------------- */

.rail-object [data-draw]{stroke-dasharray:1;stroke-dashoffset:1}
.rail[data-rail-ready="true"] .rail-panel[data-active="true"] [data-draw]{
  animation:rail-draw 320ms var(--ease) forwards;
}
.rail[data-rail-ready="true"] .rail-panel[data-active="true"] .rail-copy{
  animation:rail-slide 340ms var(--ease);
}

@keyframes rail-sweep{from{width:0}to{width:100%}}
@keyframes rail-draw{to{stroke-dashoffset:0}}
@keyframes rail-slide{from{opacity:0;transform:translate3d(30px,0,0)}to{opacity:1;transform:translate3d(0,0,0)}}

/* While the script measures every panel to find the tallest, nothing may
   animate or the six draw-ins would all fire at once behind the reader. */
.rail[data-rail-measuring="true"] *,
.rail[data-rail-measuring="true"] *::after{
  animation:none!important;transition:none!important;
}

/* ---------- Night variant -------------------------------------------------
   The same component carried into the dark platform band. Only the surface,
   ink, and accent change; geometry, timing, and behaviour are identical, so
   the two rails read as one system rather than two lookalike widgets. */

.rail--night .rail-stage{border-top-color:rgba(255,255,255,.14);border-left-color:rgba(255,255,255,.14)}
.rail--night .rail-panel{border-right-color:rgba(255,255,255,.14);border-bottom-color:rgba(255,255,255,.14)}
.rail--night .rail-n{color:var(--night-chip)}
.rail--night .rail-panel h3{color:var(--night-ink)}
.rail--night .rail-panel p{color:var(--night-lede)}

.rail--night[data-rail-ready="true"] .rail-stage{
  background:var(--night-lift);border-color:rgba(255,255,255,.14);
}
.rail--night[data-rail-ready="true"] .rail-n b{color:rgba(126,166,255,.44)}
.rail--night[data-rail-ready="true"] .rail-n i{color:var(--night-chip)}
/* These two must carry the ready-state specificity or the light-mode rail
   rules win the cascade and put dark body ink on the dark band. */
.rail--night[data-rail-ready="true"] .rail-panel h3{color:var(--night-ink)}
.rail--night[data-rail-ready="true"] .rail-panel p{color:var(--night-lede)}
.rail--night[data-rail-ready="true"] .rail-object{
  background:rgba(126,166,255,.07);border-left-color:rgba(255,255,255,.10);
  color:var(--night-accent);
}
.rail--night .rail-step{border-top-color:rgba(255,255,255,.16);color:var(--night-chip)}
.rail--night .rail-step:hover{color:var(--night-ink);border-top-color:rgba(255,255,255,.32)}
.rail--night .rail-step:active{color:var(--night-ink)}
.rail--night .rail-step[aria-selected="true"]{color:var(--night-ink);border-top-color:var(--night-accent)}
.rail--night .rail-step::after{background:var(--night-accent)}
.rail--night[data-rail-ready="true"] .rail-step[data-rail-done="true"]::after{background:rgba(126,166,255,.42)}
.rail--night .rail-step:focus-visible{outline-color:var(--night-accent)}

@media (max-width:760px){
  .rail--night[data-rail-ready="true"] .rail-object{
    border-left:0;border-bottom:1px solid rgba(255,255,255,.10);
  }
}

/* ---------- Responsive --------------------------------------------------- */

@media (max-width:1080px){
  .rail[data-rail-ready="true"] .rail-panel[data-active="true"]{
    grid-template-columns:minmax(0,1fr) 220px;min-height:268px;
  }
  .rail[data-rail-ready="true"] .rail-stage{min-height:268px}
  .rail[data-rail-ready="true"] .rail-copy{padding:36px 32px}
  .rail[data-rail-ready="true"] .rail-object svg{width:104px;height:104px}
  .rail[data-rail-ready="true"] .rail-n b{font-size:44px}
}
@media (max-width:760px){
  .rail-stage{grid-template-columns:1fr}
  .rail[data-rail-ready="true"] .rail-stage{min-height:0}
  .rail[data-rail-ready="true"] .rail-panel[data-active="true"]{
    grid-template-columns:minmax(0,1fr);grid-template-rows:132px auto;min-height:0;
  }
  .rail[data-rail-ready="true"] .rail-object{
    grid-row:1;border-left:0;border-bottom:1px solid var(--line);
  }
  .rail[data-rail-ready="true"] .rail-object svg{width:84px;height:84px}
  .rail[data-rail-ready="true"] .rail-copy{grid-row:2;padding:24px 22px 28px}
  .rail[data-rail-ready="true"] .rail-n b{font-size:38px}
  .rail[data-rail-ready="true"] .rail-panel h3{font-size:20px;margin-top:14px}
  .rail[data-rail-ready="true"] .rail-panel p{font-size:16px}
  .rail[data-rail-ready="true"] .rail-spine{gap:6px}
  .rail-step{font-size:12px;padding-top:10px}
  .rail-step-label{display:none}
}
/* At the narrowest widths six steps plus their gaps leave each target under the
   44px minimum, so the gaps give way rather than the touch target. */
@media (max-width:420px){
  .rail[data-rail-ready="true"] .rail-spine{gap:2px}
}

/* ---------- Reduced motion: no sweep, no draw, no auto-advance ----------- */

@media (prefers-reduced-motion:reduce){
  .rail[data-rail-ready="true"] .rail-step[aria-selected="true"]::after,
  .rail[data-rail-ready="true"][data-rail-playing="true"] .rail-step[aria-selected="true"]::after,
  .rail[data-rail-ready="true"] .rail-panel[data-active="true"] [data-draw],
  .rail[data-rail-ready="true"] .rail-panel[data-active="true"] .rail-copy{
    animation:none;
  }
  .rail-object [data-draw]{stroke-dashoffset:0}
  .rail[data-rail-ready="true"] .rail-panel[data-active="true"] .rail-copy{opacity:1;transform:none}
  .rail-step[aria-selected="true"]::after{transition:none}
}

/* ---------- Print: show every panel ------------------------------------- */

@media print{
  .rail[data-rail-ready="true"] .rail-stage{
    display:grid;grid-template-columns:repeat(3,1fr);border-radius:0;min-height:0;
  }
  .rail[data-rail-ready="true"] .rail-panel{
    display:block;border-right:1px solid var(--line);border-bottom:1px solid var(--line);
    padding:24px 20px;
  }
  .rail[data-rail-ready="true"] .rail-object,.rail[data-rail-ready="true"] .rail-spine{display:none}
  .rail-object [data-draw]{stroke-dashoffset:0}
  .rail[data-rail-ready="true"] .rail-panel .rail-copy{opacity:1;transform:none;animation:none}
}

/* ---------- C0137 Solution card object ------------------------------------
   The cards keep their six links, their copy, and their existing hover set.
   What they gain is depth: the 28px rule that sat above each title becomes a
   drawn object in a tinted well, from the same hand as the rail objects. A
   rotating rail would have been wrong here, since hiding five of six
   navigation targets to win a layout is a bad trade. */

.grid2--objects .card i{
  display:flex;align-items:center;justify-content:center;
  width:56px;height:56px;margin-bottom:22px;
  border-radius:var(--r-tile);background:var(--ice);color:var(--blue);
  transition:background var(--t-base) var(--ease),transform var(--t-base) var(--ease),color var(--t-base) var(--ease);
}
.grid2--objects .card i svg{width:30px;height:30px}
.grid2--objects .card-link:hover i,
.grid2--objects .card-link:focus-visible i{
  width:56px;background:var(--blue-line);color:var(--blue-deep);transform:translateY(-2px);
}
.grid2--objects .card-link:active i{transform:translateY(0)}

/* The hover must read clearly without floating. An oversized lifted panel broke
   the grid and detached from the hairlines, so the surface now sits exactly
   inside its own cell: paper fill, a blue hairline picking out the live cell,
   no shadow and no size change. The grid stays intact and nothing moves. */
.grid2--objects .card{position:relative}
.grid2--objects .card::before{
  content:"";position:absolute;z-index:-1;inset:0;
  background:transparent;box-shadow:inset 0 0 0 1px transparent;
  transition:background var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease);
}

/* Mohamed: the surface must meet the grid lines with no margin, and the air
   belongs INSIDE the card. Measuring the surface off the content (the previous
   fix) left a gap between the cell divider and the card edge, so the hover read
   as two stacked borders with a channel between them. The cards now carry real
   symmetric padding and the surface fills the cell exactly. */
.grid2--objects .card{padding:32px 32px 36px}
.grid2--objects .card:nth-child(odd),
.grid2--objects .card:nth-child(even){padding:32px 32px 36px}
.grid2--objects .card::before{inset:0}
.grid2--objects .card-link:hover::before,
.grid2--objects .card-link:focus-visible::before{
  background:var(--paper);box-shadow:inset 0 0 0 1px var(--blue-line),0 0 0 1px var(--blue-line);
}
.grid2--objects .card-link:active::before{background:var(--ice)}

/* Objects draw themselves as their card enters, and are simply present when
   the motion layer is off. */
html.home-motion-active .grid2--objects .card i [data-draw]{stroke-dasharray:1;stroke-dashoffset:1}
html.home-motion-active .grid2--objects .card[data-home-in="true"] i [data-draw]{
  animation:rail-draw 320ms var(--ease) forwards;
}

/* ---------- C0138 Closing panel -------------------------------------------
   The page ended on centred text with nothing to look at. It now closes on a
   contained panel carrying the same signal motif the call chapter opens with,
   so the last thing on the page rhymes with the first real object on it. */

.cta-panel{
  position:relative;isolation:isolate;overflow:hidden;
  border:1px solid var(--blue-line);border-radius:var(--r-card);
  background:var(--paper);padding:76px 40px 80px;
}
/* Mohamed's bleed rule: a shape may signal by running off the edge, but it must
   never cross text. The copy owns the centre column, so the signal is masked to
   the outer bands and reads as a line entering and leaving the panel. */
.cta-signal{
  position:absolute;inset:0;z-index:0;width:100%;height:100%;pointer-events:none;opacity:.9;
  -webkit-mask-image:linear-gradient(to right,#000 0,#000 13%,transparent 32%,transparent 68%,#000 87%,#000 100%);
  mask-image:linear-gradient(to right,#000 0,#000 13%,transparent 32%,transparent 68%,#000 87%,#000 100%);
}
.cta-signal-track,.cta-signal-run{fill:none;vector-effect:non-scaling-stroke}
.cta-signal-track{stroke:rgba(37,99,235,.16);stroke-width:1}
/* Three lines rather than one, each on its own curve, length and offset so they
   never travel in lockstep. The negative delays start them mid-path, so the
   panel is already alive on arrival instead of beginning from empty. */
.cta-signal-run{
  stroke:rgba(37,99,235,.44);stroke-width:1.6;stroke-linecap:round;
  stroke-dasharray:.06 .94;
  animation:call-signal-route var(--sigdur,11s) linear infinite;
  animation-delay:var(--sig,0ms);
}
.cta-body{position:relative;z-index:1}

@media (max-width:760px){
  .grid2--objects .card,
  .grid2--objects .card:nth-child(odd),
  .grid2--objects .card:nth-child(even){padding:26px 20px 30px}
  .grid2--objects .card::before{inset:0}
  .grid2--objects .card i{width:48px;height:48px;margin-bottom:18px}
  .grid2--objects .card i svg{width:26px;height:26px}
  .grid2--objects .card-link:hover i{width:48px}
  .cta-panel{padding:52px 22px 56px;border-radius:var(--r-tile)}
  /* Narrow panels have no clear outer bands: the copy runs nearly edge to edge,
     so a side mask would let the lines cross it. Switch to top and bottom bands,
     which are the only genuinely empty parts of the panel at this width. */
  .cta-signal{
    -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 13%,transparent 26%,transparent 74%,#000 87%,#000 100%);
    mask-image:linear-gradient(to bottom,#000 0,#000 13%,transparent 26%,transparent 74%,#000 87%,#000 100%);
  }
}
@media (prefers-reduced-motion:reduce){
  .cta-signal-run{animation:none}
  html.home-motion-active .grid2--objects .card i [data-draw]{stroke-dashoffset:0}
  html.home-motion-active .grid2--objects .card[data-home-in="true"] i [data-draw]{animation:none}
}
@media print{
  .cta-signal{display:none}
  .grid2--objects .card i [data-draw]{stroke-dashoffset:0}
}

/* ---------- Hero chip rule ------------------------------------------------
   The three hero chips were three equal blocks of text divided by hairlines,
   with nothing to anchor them. A short accent rule gives each one a head
   without implying it is clickable, since none of them are. All three read
   the same, because none of them is more important than the others and the
   hero's one accent moment belongs to the primary action. */

.chips>div::before{
  content:"";display:block;width:22px;height:2px;border-radius:2px;
  background:var(--blue-line);margin-bottom:16px;
}

/* ---------- Call visibility tiles ----------------------------------------
   These read as data rows, so they get the scanning affordance data rows
   want: the row lifts out of the board on hover, the label brightens. */

.board .tile{
  margin-inline:-12px;padding-inline:12px;border-radius:var(--r-field);
  transition:background var(--t-base) var(--ease);
}
.board .tile:hover{background:rgba(255,255,255,.06)}
.board .tile span{transition:color var(--t-base) var(--ease)}
.board .tile:hover span{color:var(--night-accent)}

@media (max-width:760px){
  .chips>div::before{margin-bottom:12px}
}
@media (prefers-reduced-motion:reduce){
  .board .tile,.board .tile span{transition:none}
}


.chips>div::before{transform-origin:left center}
html.home-motion-active .chips>div::before{
  transform:scaleX(0);
  animation:rule-draw 700ms cubic-bezier(.19,1,.22,1) forwards;
}
html.home-motion-active .chips>div:nth-child(2)::before{animation-delay:110ms}
html.home-motion-active .chips>div:nth-child(3)::before{animation-delay:220ms}

@keyframes rule-draw{to{transform:scaleX(1)}}

@media (prefers-reduced-motion:reduce){
  html.home-motion-active .chips>div::before{animation:none;transform:scaleX(1)}
}
