/*
  ip.nirmaan.online: only what is IP Nirmaan's own.

  Everything shared with nirmaan.online (tokens, type, nav, menu, buttons,
  section heads, cards, hero, closing band, footer, dock, reveal motion) comes
  from /nirmaan.css, nirmaan.online's stylesheet copied unchanged, so the two
  sites cannot drift. This file adds the components only this site has:
  the plan terminal, the assurance ladder, the "How it works" scene, the
  organization numbers, the constitution articles, the VeriTriage graph and
  the status columns. It uses nirmaan.css's tokens and type, never its own.
*/
@layer reset, base, layout, components, pages, motion;

@layer pages {

  /* The terminal stays dark in both themes, like a real one. */
  :root {
    --term-bg: #131313; --term-fg: #EDEDE7; --term-dim: #9A9A93; --term-blue: #8190FF;
    --term-line: rgb(237 237 231 / 0.12);
  }
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --term-bg: #17171A; } }
  :root[data-theme="dark"] { --term-bg: #17171A; }

  code { font-family: var(--mono); font-size: 0.92em; }

  /* Headings inside this site's components use nirmaan.css's card heading. */
  .status__col h3 {
    font-family: var(--display); font-weight: 750; font-stretch: 104%;
    font-size: 1.3rem; letter-spacing: -0.015em; line-height: 1.2;
  }

  .replay, .term__replay {
    font-family: var(--mono); font-size: var(--fs-mono); letter-spacing: 0.12em; text-transform: uppercase;
    padding: 0.5rem 0.75rem; min-height: 2.75rem; border: 1px solid var(--line-2); color: var(--ink-2);
    transition: color 0.2s, border-color 0.2s;
  }
  .replay:hover, .term__replay:hover { color: var(--blue); border-color: var(--blue); }

  /* A section on the ink ground (the organization numbers). */
  .section--ink { background: var(--ink); color: var(--paper); }
  .section + .section--ink, .section--ink + .section { border-top-color: transparent; }
  .section--ink .section__text { color: color-mix(in srgb, var(--paper) 72%, transparent); }

  /* GATE: a human-approval gate, in nirmaan.css's .gate style (blue, mono caps). */
  .gate-tag {
    display: inline-block; padding: 0.05rem 0.4rem; margin-right: 0.35rem;
    background: var(--blue); color: var(--blue-ink);
    font-family: var(--mono); font-size: 0.6875rem; font-weight: 400; letter-spacing: 0.12em; text-transform: uppercase;
  }

  /* The constitution: nirmaan.css's card grid, the article number in place of a glyph. */
  .article__id {
    justify-self: start; padding: 0.15rem 0.45rem; margin-bottom: var(--s1);
    font-family: var(--mono); font-size: var(--fs-mono); letter-spacing: 0.12em;
    color: var(--blue); border: 1px solid currentColor;
  }

  /* Sized so the graph labels sit near body-text size. */
  .graph { max-width: 38rem; margin-inline: auto; }

  /* ---- Terminal ---- */
  .term { min-width: 0; }
  .term__bar {
    display: flex; align-items: center; gap: var(--s2); min-height: 2.75rem; padding: 0 0 0 var(--s2);
    background: var(--term-bg); color: var(--term-dim); border-bottom: 1px solid var(--term-line);
    font-family: var(--mono); font-size: var(--fs-mono);
  }
  .term__dots { display: inline-flex; gap: 6px; }
  .term__dots i { width: 8px; height: 8px; background: var(--term-line); }
  .term__title { margin-right: auto; }
  .term__replay { border: 0; border-left: 1px solid var(--term-line); color: var(--term-dim); }
  .term__replay:hover { color: var(--term-blue); }
  .term__body {
    margin: 0; padding: var(--s3) var(--s3) var(--s4);
    background: var(--term-bg); color: var(--term-fg);
    font-family: var(--mono); font-size: clamp(0.6875rem, 0.62rem + 0.28vw, 0.8125rem); line-height: 1.7;
    overflow-x: auto; overscroll-behavior-x: contain; tab-size: 4;
  }
  .term__body:focus-visible { outline-offset: -2px; }
  /* Lines stay inline: the newlines in the <pre> already break them. */
  .term__body .ln { display: inline; }
  .term__body b { color: var(--term-fg); font-weight: 500; }
  .term__body .prompt { color: var(--term-blue); }
  .term__body .k, .term__body .o { color: var(--term-dim); }
  /* In the terminal, GATE keeps the terminal's own type and colours. */
  .term__body .gate-tag { margin-right: 0; padding: 0 0.35em; font-size: inherit; letter-spacing: 0; text-transform: none; color: var(--term-bg); background: var(--term-blue); }
  .term__body .human { color: var(--term-blue); }
  .term figcaption, .graph figcaption, .org figcaption {
    margin-top: var(--s2); font-family: var(--mono); font-size: var(--fs-mono); color: var(--ink-3);
  }

  /* ---- Assurance ladder ---- */
  .ladder { margin-top: var(--s6); padding: var(--s4); border: 1px solid var(--line-2); background: var(--paper-2); }
  .ladder__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); margin-bottom: var(--s4); }
  .ladder__head figcaption { color: var(--ink-2); }
  .ladder__head .eyebrow { margin: 0 0.75em 0 0; }
  .ladder__rungs { display: grid; gap: var(--s2); grid-template-columns: repeat(4, 1fr); }
  .rung {
    display: grid; gap: 0.35rem; padding: var(--s3) var(--s2);
    border: 1px solid var(--ink); background: var(--paper);
  }
  .rung__state {
    font-family: var(--mono); font-size: 0.875rem; font-weight: 500; color: var(--blue);
    display: inline-flex; align-items: center; gap: 0.5em;
  }
  .rung__state::before { content: ""; width: 0.6rem; height: 0.6rem; background: currentColor; flex: none; }
  .rung__need { font-size: var(--fs-small); color: var(--ink-2); }
  .ladder__track { position: relative; height: 1px; margin-top: var(--s3); background: var(--line-2); }
  /* The token rides a full-width rail, so moving the rail by 25% of its own
     width moves the token exactly one rung. Resting state: the top rung. */
  .ladder__token { position: absolute; left: 0; right: 0; top: -5px; height: 11px; transform: translateX(75%); }
  .ladder__token::before { content: ""; position: absolute; left: calc(12.5% - 5px); width: 11px; height: 11px; background: var(--blue); }
  .ladder__refusal { margin-top: var(--s4); display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.75em; color: var(--ink-2); font-size: var(--fs-small); }
  .refused {
    font-family: var(--mono); font-size: var(--fs-mono); text-transform: uppercase; letter-spacing: 0.08em;
    padding: 0.2em 0.6em; border: 1px solid var(--ink); color: var(--ink);
  }
  @media (max-width: 47.99rem) {
    .ladder { padding: var(--s3); }
    .ladder__head { flex-wrap: wrap; }
    .ladder__rungs { grid-template-columns: 1fr 1fr; }
    .ladder__track { display: none; }
  }

  /* ---- How it works: the machine inside the scene ----
     The scene itself (pinning, steps, fitting) is nirmaan.css's .build.
     Resting state (no motion) is the finished diagram, in normal flow:
     the five steps beside the machine, every task in its final state. */

  .machine { display: grid; gap: var(--s2); padding: var(--s3); border: 1px solid var(--line-2); background: var(--paper-2); }
  .intake__label {
    display: block; margin-bottom: 0.2rem; font-family: var(--mono); font-size: 0.6875rem;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3);
  }
  .intake { padding: 0.75rem var(--s2); background: var(--paper); border: 1px solid var(--ink); font-family: var(--mono); font-size: 0.9375rem; }
  .chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }
  .chips li { padding: 0.15rem 0.55rem; font-family: var(--mono); font-size: 0.8125rem; color: var(--blue); border: 1px solid var(--blue); background: var(--blue-wash); }
  .assume { margin-top: 0.6rem; font-size: 0.875rem; color: var(--ink-2); }
  /* Each row carries its own border, so rows not yet routed leave no empty box. */
  .tasks { display: grid; }
  .task + .task { border-top-width: 0; }
  .task {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) 7.25rem; gap: var(--s2); align-items: center;
    padding: 0.5rem 0.75rem; background: var(--paper); font-size: 0.875rem; border: 1px solid var(--line);
  }
  .task__name { font-weight: 600; }
  .task__owner { color: var(--ink-2); font-size: 0.8125rem; }
  .task .human { color: var(--blue); }
  .task__state {
    justify-self: end; padding: 0.1rem 0.5rem; white-space: nowrap;
    font-family: var(--mono); font-size: 0.75rem; color: var(--ink-3); border: 1px solid var(--line-2);
    transition: color 0.3s, background-color 0.3s, border-color 0.3s;
  }
  .task__state[data-state="executed"] { color: var(--ink); border-color: var(--ink); }
  .task__state[data-state="verified"] { color: var(--blue); border-color: var(--blue); background: var(--blue-wash); }
  .task__state[data-state="awaits human"] { color: var(--ink); border: 1px dashed var(--ink); }
  .task__state[data-state="approved"] { color: var(--blue-ink); background: var(--blue); border-color: var(--blue); }
  .machine__out { padding: 0.6rem var(--s2); border: 1px solid var(--blue); background: var(--paper); font-size: 0.875rem; }
  .chain { display: flex; align-items: center; gap: var(--s2); }
  .chain__label { flex: none; font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
  .chain__blocks { display: flex; flex-wrap: wrap; gap: 3px; }
  .chain__blocks i { width: 0.625rem; height: 0.625rem; background: var(--ink); }
  .machine figcaption { font-family: var(--mono); font-size: var(--fs-mono); color: var(--ink-3); }
  @media (max-width: 63.99rem) {
    .machine { padding: var(--s2); }
    .task { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.1rem; column-gap: var(--s1); padding: 0.4rem 0.6rem; }
    .task__state { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
    .task__owner { grid-column: 1; font-size: 0.75rem; }
  }
  /* Phones: the machine packs tighter so the whole scene can stay pinned
     between the nav and the dock. Nothing is dropped, only spacing. */
  @media (max-width: 40rem) {
    .machine { gap: 0.6rem; padding: 0.75rem; }
    .intake { padding: 0.5rem 0.75rem; font-size: 0.8125rem; }
    .chips { margin-top: 0.4rem; gap: 0.3rem; }
    .chips li { font-size: 0.6875rem; padding: 0.05rem 0.4rem; }
    .assume { margin-top: 0.4rem; font-size: 0.75rem; }
    .assume .intake__label { display: inline; margin-right: 0.35rem; }
    .task { padding: 0.3rem 0.5rem; font-size: 0.8125rem; line-height: 1.35; }
    .task__owner { font-size: 0.6875rem; }
    .machine__out { padding: 0.4rem 0.75rem; font-size: 0.8125rem; }
    .machine__out .intake__label { display: inline; margin-right: 0.35rem; }
    .machine figcaption { font-size: 0.625rem; line-height: 1.45; }
  }

  /* ---- Stats and org ---- */
  .stats { display: grid; gap: 1px; background: color-mix(in srgb, var(--paper) 14%, transparent); border: 1px solid color-mix(in srgb, var(--paper) 14%, transparent);
           grid-template-columns: repeat(2, 1fr); }
  /* Seven tiles: 2 + 2 + 2 + 1 wide on phones, 4 + 3 wide on tablets, one row on desktop. */
  .stat:last-child { grid-column: span 2; }
  @media (min-width: 48rem) { .stats { grid-template-columns: repeat(4, 1fr); } }
  @media (min-width: 72rem) { .stats { grid-template-columns: repeat(7, 1fr); } .stat:last-child { grid-column: auto; } }
  .stat { display: grid; align-content: start; gap: var(--s1); padding: var(--s4) var(--s3); background: var(--ink); }
  .stat__num { font-family: var(--display); font-weight: 800; font-size: clamp(2.5rem, 1.9rem + 2.4vw, 3.75rem); line-height: 1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
  .stat__label { font-size: var(--fs-small); color: color-mix(in srgb, var(--paper) 72%, transparent); }

  .org { margin-top: var(--s6); }
  .org__root { display: flex; justify-content: center; position: relative; padding-bottom: var(--s4); }
  .org__root span {
    font-family: var(--display); font-weight: 800; padding: var(--s2) var(--s4);
    background: var(--blue-on-ink); color: var(--ink);
  }
  .org__root::after { content: ""; position: absolute; left: 50%; bottom: 0; width: 1px; height: var(--s4); background: color-mix(in srgb, var(--paper) 40%, transparent); transform-origin: top; }
  .org__divs {
    display: grid; gap: var(--s1); grid-template-columns: repeat(2, 1fr);
    padding-top: var(--s2); border-top: 1px solid color-mix(in srgb, var(--paper) 40%, transparent);
  }
  .org__divs li {
    display: grid; place-items: center;
    padding: var(--s2); border: 1px solid color-mix(in srgb, var(--paper) 28%, transparent);
    font-size: var(--fs-small); font-weight: 600; text-align: center;
  }
  @media (min-width: 48rem) { .org__divs { grid-template-columns: repeat(5, 1fr); } }
  .section--ink .org figcaption { color: color-mix(in srgb, var(--paper) 66%, transparent); text-align: center; }

  /* ---- VeriTriage ---- */
  .graph svg { width: 100%; height: auto; overflow: visible; }
  .graph rect { fill: var(--paper); stroke: var(--ink); stroke-width: 1; }
  .graph text { font-family: var(--mono); font-size: 13px; fill: var(--ink); text-anchor: middle; }
  .graph text.sub { font-size: 10px; fill: var(--ink-3); }
  .graph__ev rect { fill: var(--paper-2); }
  .graph__edges path { fill: none; stroke: var(--ink-3); stroke-width: 1; }
  .graph__rank rect.top { fill: var(--blue); stroke: var(--blue); }
  .graph__rank rect.top + text, .graph__rank rect.top + text + text { fill: var(--blue-ink); }

  /* ---- Status ---- */
  .status { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
  .status__col { padding-top: var(--s3); border-top: 2px solid var(--ink); }
  .status__col h3 { display: flex; align-items: center; gap: 0.6em; margin-bottom: var(--s2); }
  .status__col p { color: var(--ink-2); }
  .mark { width: 0.75rem; height: 0.75rem; flex: none; border: 1.5px solid var(--blue); }
  .status__col--now .mark { background: var(--blue); }
  .status__col--next .mark { background: linear-gradient(90deg, var(--blue) 50%, transparent 50%); }

}


/* Motion: only under html.motion (set in <head>), as on nirmaan.online. */
@layer motion {
  /* ---- Terminal: motion.js prints it line by line ---- */
  /* The plan is painted in full from the first frame, in the terminal's dim
     grey (still AA contrast), so it never delays the page's largest paint.
     Printing then lights it line by line and stamps each GATE. The command
     line itself types. */
  .motion .term.is-printing .ln:not(.is-shown),
  .motion .term.is-printing .ln:not(.is-shown) * { color: var(--term-dim); background: none; }
  .motion .term.is-printing .cmd:not(.is-shown) { visibility: hidden; }
  .motion .term .ln, .motion .term .ln * { transition: color 0.3s var(--ease-out); }
  .motion .term .cmd.is-typing::after {
    content: ""; display: inline-block; width: 0.55em; height: 1.1em; margin-left: 1px;
    vertical-align: -0.2em; background: var(--term-blue); animation: blink 1s steps(1) infinite;
  }
  @keyframes blink { 50% { opacity: 0; } }
  .motion .term .ln.is-shown .gate-tag { animation: stamp 0.45s var(--ease-out) both; display: inline-block; }
  @keyframes stamp { from { transform: scale(1.6); opacity: 0; } }

  /* ---- Assurance ladder: latch ----
     The token climbs one rung at a time (0.2s, 1.2s, 2.2s, 3.2s), and each
     rung latches as the token arrives. Then the refusal lands. */
  .motion .ladder:not(.is-playing) .rung { border-color: var(--line-2); }
  .motion .ladder:not(.is-playing) .rung__state { color: var(--ink-3); }
  .motion .ladder:not(.is-playing) .rung__state::before { transform: scale(0); }
  .motion .ladder:not(.is-playing) :is(.ladder__token, .ladder__refusal) { opacity: 0; }

  .motion .ladder.is-playing .rung { animation: latch-box 0.5s var(--ease-out) both; animation-delay: calc(0.2s + var(--r) * 1s); }
  .motion .ladder.is-playing .rung__state { animation: latch-text 0.5s var(--ease-out) both; animation-delay: calc(0.2s + var(--r) * 1s); }
  .motion .ladder.is-playing .rung__state::before { animation: latch-cell 0.5s var(--ease-out) both; animation-delay: calc(0.2s + var(--r) * 1s); }
  @keyframes latch-box  { from { border-color: var(--line-2); transform: translateY(0.25rem); } }
  @keyframes latch-text { from { color: var(--ink-3); } }
  @keyframes latch-cell { from { transform: scale(0); } 60% { transform: scale(1.4); } }

  .motion .ladder.is-playing .ladder__token { animation: climb 3.4s var(--ease-in-out) both; }
  @keyframes climb {
    0%   { transform: translateX(0); opacity: 0; }
    6%   { opacity: 1; }
    24%  { transform: translateX(0); }
    35%, 53% { transform: translateX(25%); }
    65%, 82% { transform: translateX(50%); }
    94%, 100% { transform: translateX(75%); opacity: 1; }
  }
  .motion .ladder.is-playing .ladder__refusal { animation: fade-up 0.6s var(--ease-out) both 4s; }
  .motion .ladder.is-playing .refused { animation: refuse 0.5s var(--ease-out) both 4.3s; }
  @keyframes refuse { 0% { transform: translateX(0); } 25% { transform: translateX(-4px); } 50% { transform: translateX(4px); } 75% { transform: translateX(-2px); } }

  /* ---- How it works: the machine's own moves, on nirmaan.css's pinned
     scene (.build.is-pinned sets --t and each chip's state). ---- */
  .build.is-pinned .chips [data-at] { transform: scale(calc(0.6 + var(--t, 0) * 0.4)); }
  .build.is-pinned .task[data-at] { transform: translateX(calc((1 - var(--t, 0)) * -2.5rem)); }
  .build.is-pinned .chain__blocks [data-at] { transform: translateY(calc((1 - var(--t, 0)) * -0.6rem)); }

  /* ---- Organization: the root lands, the trunk draws, divisions drop in ---- */
  .motion .org .org__root::after { transition: transform 0.6s var(--ease-out) 0.4s; }
  .motion .org:not(.is-in) .org__root::after { transform: scaleY(0); }
  .motion .org .org__divs { transition: border-color 0.8s var(--ease-out) 0.7s; }
  .motion .org:not(.is-in) .org__divs { border-top-color: transparent; }
  .motion .org .org__divs li { transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out); transition-delay: calc(0.8s + var(--k) * 60ms); }
  .motion .org:not(.is-in) .org__divs li { opacity: 0; transform: translateY(-0.75rem); }

  /* ---- VeriTriage graph: sources, edges drawn, evidence, then the ranking ---- */
  .motion .graph path { stroke-dasharray: 1; }
  .motion .graph:not(.is-playing) path { stroke-dashoffset: 1; }
  .motion .graph:not(.is-playing) :is(.graph__src, .graph__ev, .graph__rank) { opacity: 0; }
  .motion .graph.is-playing .graph__src  { animation: fade 0.6s var(--ease-out) both; }
  .motion .graph.is-playing path { animation: draw 0.9s var(--ease-in-out) both 0.5s; }
  .motion .graph.is-playing path:nth-child(n+5) { animation-delay: 1.6s; }
  .motion .graph.is-playing .graph__ev   { animation: fade 0.5s var(--ease-out) both 1.2s; }
  .motion .graph.is-playing .graph__rank { animation: fade 0.5s var(--ease-out) both 2.3s; }
  .motion .graph.is-playing .graph__rank rect.top { animation: rank-top 0.6s var(--ease-out) both 2.7s; }
  .motion .graph.is-playing .graph__rank rect.top ~ text:nth-of-type(-n+2) { animation: rank-top-text 0.6s var(--ease-out) both 2.7s; }
  @keyframes draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
  @keyframes rank-top { from { fill: var(--paper); stroke: var(--ink); } }
  @keyframes rank-top-text { from { fill: var(--ink); } }
}
