/* ————————————————————————————————————————————————————————————
   calc.css — the worksheet. One page: /calc.

   Loaded AFTER course.css, which this page uses for everything structural: the
   masthead, the crumb, the buttons, the footer, and both rooms of the light
   switch. Nothing in here restyles any of that.

   ONE IDEA: the page is the paper the arithmetic is done on.

   The sheet under a course page is an answer sheet — the paper that exam is
   taken on. Under a room sheet it is a drafting grid. Under this one it is
   graph paper, because that is what you reach for when you are converting a
   number by hand.

   Everything colours through course.css's semantic layer, so the blackout
   comes free.
   ———————————————————————————————————————————————————————————— */

/* ————————————————————————————————————————————————————————————
   THE SHEET, RULED SQUARE

   room.css's technique, one module smaller. The argument there holds here and
   is not repeated: verticals can pass behind running text because the eye reads
   them as column edges; a horizontal hairline behind body copy is a second,
   misaligned leading and the eye catches it every time. So the horizontals live
   in the outer margins only, and below the width where a margin exists they do
   not exist either.

   What changes is the module. The room's grid is 68.335px — the 820px measure
   in twelve. This one is 34.1675px, the same measure in twenty-four, because
   graph paper is finer than a drafting grid and because halving keeps every
   coarser rule where room.css put it: the heavy line still falls every eight
   modules, at 273.34px, which is 820 in three — so it still lands exactly on
   the column edge at 50% ± 410. The page is laid out ON the grid, not over it.
   ———————————————————————————————————————————————————————————— */

/* the dawn stays — it is the brand's one light, and it is what the title sits
   IN. What goes is the desk falloff course.css adds at ≥1024px: it darkens both
   inline edges, which is exactly the strip the graph paper occupies, and a grid
   plus a shadow around the same column is two frames doing one job. One idea per
   page. room.css drops it for the same reason and this sheet rules its margins
   harder, so it has more to lose. Re-declaring background-image on the class
   beats the media query on specificity; background-COLOUR is left alone, so
   --paper still comes from body. */
body.sheet-calc{
  background-image:
    radial-gradient(circle 560px at 88% -130px, rgba(224,86,143,.10), rgba(224,86,143,0) 66%);
  background-repeat: no-repeat;
  background-size: 100% 620px;
}
:root[data-room="dark"] body.sheet-calc{
  background-image:
    radial-gradient(circle 560px at 88% -130px, rgba(224,86,143,.09), rgba(224,86,143,0) 66%);
}

body.sheet-calc::before,
body.sheet-calc::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
}

/* the fine verticals, full bleed, at every width */
body.sheet-calc::before{
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34.1675' height='34.1675'%3E%3Cpath d='M.5 0V34.1675' fill='none' stroke='%230c0a09' stroke-opacity='.05'/%3E%3C/svg%3E");
  background-repeat:repeat; background-position:center top;
  background-size:34.1675px 34.1675px;
  /* starts under the masthead, stops before the footer — course.css's rule, so
     the two elements that have to read as chrome never sit on ruled paper */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 150px, #000 calc(100% - 300px), transparent calc(100% - 140px));
          mask-image: linear-gradient(to bottom, transparent 0, #000 150px, #000 calc(100% - 300px), transparent calc(100% - 140px));
}

/* the squares closed, the heavy rule — and the figures. Margins only.

   THE FIGURES: the tables this page used to print came out as text and went
   back in as geometry. Someone has already worked on this sheet:

   · beside the input rows, the raw→score conversion CURVE — all forty-seven
     true points of the verbal table, plotted with point ticks, and the
     worked example (21 → 91) ringed with its dashed construction dropped
     to both axes, the way a hand does it on real graph paper;
   · beside the result block, the published score DISTRIBUTION — the bell
     the percentile sentence reads from, on its own graduated baseline;
   · beside the pivot card, the BAND TABLE that turns a weighted score into
     a general one — its twenty rows drawn as twenty rungs, each from its
     row's low corner to its high one and none joined to the next, because a
     weighted score is a whole number and the table holds nothing between
     one row and the following. The flat at each end is a clamp the engine
     returns outside the table: 200 at fifty and under, 800 at a hundred and
     fifty and over;
   · beside the ask, the YAELNET conversion — forty-five points from the
     official score-calculation guide, a different animal: one point of
     scale per raw answer for the first ten, three and four per raw at the
     top;
   · and where the column edges meet the sheet's top and bottom fades, four
     REGISTRATION marks, the way a drawing is squared to its plate.

   Every coordinate is generated from the engine's own tables (the same
   arrays calc.html ships), so the margins are provably true — reference
   figures, not decoration. Drawn in the grid's own two inks, a step above
   its opacity, so they sit ON the paper as figure over ground. They live on
   this margins-only layer and vanish with it below 1024px: no margin, no
   room for plots.

   WHERE THEY SIT: a background-position percentage resolves against (area −
   image), not against the area, so a figure asking for 50% + 422px lands
   half its own width further in — inside the reading column, where the mask
   below eats it. The offset each one needs is therefore 422 plus half its
   width, which puts every inner edge on 50% ± 422: ten pixels clear of the
   mask's opaque boundary, and one gutter for all four. The registration
   image carries its two marks 820px apart — the column's exact width — so
   centring it drops one on each edge at 50% ± 410, at any viewport. */
body.sheet-calc::after{
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='300'%3E%3Cpath d='M4 296 L8.2 293.2 L12.3 290.4 L16.5 287.6 L20.7 284.8 L24.9 279.2 L29 273.6 L33.2 268 L37.4 262.4 L41.6 256.8 L45.7 251.2 L49.9 245.6 L54.1 240 L58.3 231.6 L62.4 226 L66.6 220.4 L70.8 214.8 L75 209.2 L79.1 200.8 L83.3 195.2 L87.5 189.6 L91.7 181.2 L95.8 175.6 L100 167.2 L104.2 161.6 L108.3 153.2 L112.5 147.6 L116.7 142 L120.9 133.6 L125 128 L129.2 122.4 L133.4 116.8 L137.6 108.4 L141.7 102.8 L145.9 94.4 L150.1 88.8 L154.3 83.2 L158.4 74.8 L162.6 69.2 L166.8 60.8 L171 55.2 L175.1 49.6 L179.3 41.2 L183.5 35.6 L187.7 27.2 L191.8 21.6 L196 16' fill='none' stroke='%230c0a09' stroke-opacity='.20' stroke-width='1.3'/%3E%3Cpath d='M2 296 h4 M4 294 v4 M18.7 284.8 h4 M20.7 282.8 v4 M35.4 262.4 h4 M37.4 260.4 v4 M52.1 240 h4 M54.1 238 v4 M68.8 214.8 h4 M70.8 212.8 v4 M85.5 189.6 h4 M87.5 187.6 v4 M102.2 161.6 h4 M104.2 159.6 v4 M118.9 133.6 h4 M120.9 131.6 v4 M135.6 108.4 h4 M137.6 106.4 v4 M152.3 83.2 h4 M154.3 81.2 v4 M169 55.2 h4 M171 53.2 v4 M185.7 27.2 h4 M187.7 25.2 v4 M194 16 h4 M196 14 v4' fill='none' stroke='%230c0a09' stroke-opacity='.16'/%3E%3Cpath d='M4 16 V296 H196 M4 296 v5 M45.7 296 v5 M87.5 296 v5 M129.2 296 v5 M171 296 v5 M196 296 v5 M4 296 h-4 M4 226 h-4 M4 156 h-4 M4 86 h-4 M4 16 h-4' fill='none' stroke='%230c0a09' stroke-opacity='.13'/%3E%3Cpath d='M91.7 296 V181.2 H4' fill='none' stroke='%230c0a09' stroke-opacity='.11' stroke-dasharray='3 3'/%3E%3Cpath d='M91.7 181.2 m-2.6 0 a2.6 2.6 0 1 0 5.2 0 a2.6 2.6 0 1 0 -5.2 0' fill='none' stroke='%230c0a09' stroke-opacity='.16'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='120'%3E%3Cpath d='M4 106.5 C8 105.6 19.2 107.4 27.8 101 C36.5 94.6 49.8 75.3 55.8 68 C61.8 60.7 61.2 58.8 63.8 57 C66.5 55.2 69.2 58.8 71.8 57 C74.5 55.2 77.2 49.7 79.8 46 C82.5 42.3 85.2 36.8 87.8 35 C90.5 33.2 93.2 35 95.8 35 C98.5 35 101.2 35 103.8 35 C106.5 35 109.2 35 111.8 35 C114.5 35 117.2 35 119.8 35 C122.5 35 125.2 36.8 127.8 35 C130.5 33.2 133.2 24 135.8 24 C138.5 24 141.2 31.3 143.8 35 C146.5 38.7 149.2 42.3 151.8 46 C154.5 49.7 157.2 51.5 159.8 57 C162.5 62.5 163.8 71.6 167.8 79 C171.9 86.4 179.3 96.3 184 101.1 C188.7 106 194 106.8 196 107.9' fill='none' stroke='%230c0a09' stroke-opacity='.19' stroke-width='1.3'/%3E%3Cpath d='M4 112 H196 M4 112 v5 M52 112 v5 M100 112 v5 M148 112 v5 M196 112 v5' fill='none' stroke='%230c0a09' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='240'%3E%3Cpath d='M4 230 L12.7 230 M14.5 222.4 L21.5 212.7 M23.2 212.4 L30.2 202.6 M31.9 202.3 L38.9 192.6 M40.7 192.2 L47.6 182.1 M49.4 181.8 L56.4 172 M58.1 171.7 L65.1 162 M66.8 161.6 L73.8 151.5 M75.6 151.2 L82.5 141.4 M84.3 141.1 L91.3 131.4 M93 131 L100 120.9 M101.7 120.6 L108.7 110.8 M110.5 110.5 L117.5 100.8 M119.2 100.4 L126.2 90.7 M127.9 90.3 L134.9 80.2 M136.7 79.9 L143.6 70.2 M145.4 69.8 L152.4 60.1 M154.1 59.7 L161.1 49.6 M162.8 49.3 L169.8 39.6 M171.6 39.2 L178.5 28 M180.3 27.7 L185.5 15.8 M187.3 14 L196 14' fill='none' stroke='%230c0a09' stroke-opacity='.19' stroke-width='1.3'/%3E%3Cpath d='M12.5 222.4 h4 M14.5 220.4 v4 M47.4 181.8 h4 M49.4 179.8 v4 M82.3 141.1 h4 M84.3 139.1 v4 M117.2 100.4 h4 M119.2 98.4 v4 M152.1 59.7 h4 M154.1 57.7 v4' fill='none' stroke='%230c0a09' stroke-opacity='.15'/%3E%3Cpath d='M4 14 V230 H196 M12.7 230 v5 M56.4 230 v5 M100 230 v5 M143.6 230 v5 M187.3 230 v5 M4 230 h-4 M4 176 h-4 M4 122 h-4 M4 68 h-4 M4 14 h-4' fill='none' stroke='%230c0a09' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='150'%3E%3Cpath d='M4 140 L7.9 138.7 L11.8 137.4 L15.7 136.1 L19.6 134.8 L23.5 133.5 L27.5 132.2 L31.4 130.9 L35.3 129.6 L39.2 128.3 L43.1 127 L47 124.4 L50.9 121.8 L54.8 117.9 L58.7 115.3 L62.6 112.7 L66.5 110.1 L70.5 106.2 L74.4 103.6 L78.3 99.7 L82.2 97.1 L86.1 93.2 L90 90.6 L93.9 86.7 L97.8 84.1 L101.7 80.2 L105.6 77.6 L109.5 75 L113.5 71.1 L117.4 68.5 L121.3 65.9 L125.2 62 L129.1 59.4 L133 55.5 L136.9 52.9 L140.8 49 L144.7 45.1 L148.6 39.9 L152.5 36 L156.5 32.1 L160.4 26.9 L164.3 23 L168.2 19.1 L172.1 15.2 L176 10' fill='none' stroke='%230c0a09' stroke-opacity='.19' stroke-width='1.3'/%3E%3Cpath d='M2 140 h4 M4 138 v4 M21.5 133.5 h4 M23.5 131.5 v4 M41.1 127 h4 M43.1 125 v4 M60.6 112.7 h4 M62.6 110.7 v4 M80.2 97.1 h4 M82.2 95.1 v4 M99.7 80.2 h4 M101.7 78.2 v4 M119.3 65.9 h4 M121.3 63.9 v4 M138.8 49 h4 M140.8 47 v4 M158.4 26.9 h4 M160.4 24.9 v4 M174 10 h4 M176 8 v4' fill='none' stroke='%230c0a09' stroke-opacity='.15'/%3E%3Cpath d='M4 10 V140 H176 M4 140 v5 M47 140 v5 M90 140 v5 M133 140 v5 M176 140 v5 M4 140 h-4 M4 107.5 h-4 M4 75 h-4 M4 42.5 h-4 M4 10 h-4' fill='none' stroke='%230c0a09' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='834' height='14'%3E%3Cpath d='M7 0 V14 M0 7 H14 M3 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 M827 0 V14 M820 7 H834 M823 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0' fill='none' stroke='%230c0a09' stroke-opacity='.12'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='834' height='14'%3E%3Cpath d='M7 0 V14 M0 7 H14 M3 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 M827 0 V14 M820 7 H834 M823 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0' fill='none' stroke='%230c0a09' stroke-opacity='.12'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='273.34' height='273.34'%3E%3Cpath d='M.5 0V273.34' fill='none' stroke='%230c0a09' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='273.34' height='273.34'%3E%3Cpath d='M0 .5H273.34' fill='none' stroke='%230c0a09' stroke-opacity='.10'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34.1675' height='34.1675'%3E%3Cpath d='M0 .5H34.1675' fill='none' stroke='%230c0a09' stroke-opacity='.05'/%3E%3C/svg%3E");
  background-repeat:no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat, repeat;
  background-position:calc(50% + 522px) 190px, calc(50% - 522px) 700px, calc(50% + 522px) 1372px, calc(50% - 512px) 1762px, center 170px, center calc(100% - 334px), center top, center top, center top;
  background-size:200px 300px, 200px 120px, 200px 240px, 180px 150px, 834px 14px, 834px 14px, 273.34px 273.34px, 273.34px 273.34px, 34.1675px 34.1675px;
  /* two masks, intersected: keep out of the reading column, AND observe the
     same top-and-tail as the verticals. 412 rather than 410 so the major rule
     sitting on the column edge is still all but fully inked; the fade finishes
     at 352, where the content inside the wrap's padding actually begins.
     Where `intersect` is unsupported the pair falls back to a union — the grid
     shows through the column too, quieter than nothing, so a floor not a bug. */
  -webkit-mask-image:
    linear-gradient(to right, #000 0, #000 calc(50% - 412px), transparent calc(50% - 352px), transparent calc(50% + 352px), #000 calc(50% + 412px), #000 100%),
    linear-gradient(to bottom, transparent 0, #000 150px, #000 calc(100% - 300px), transparent calc(100% - 140px));
          mask-image:
    linear-gradient(to right, #000 0, #000 calc(50% - 412px), transparent calc(50% - 352px), transparent calc(50% + 352px), #000 calc(50% + 412px), #000 100%),
    linear-gradient(to bottom, transparent 0, #000 150px, #000 calc(100% - 300px), transparent calc(100% - 140px));
  -webkit-mask-composite:source-in; mask-composite:intersect;
}

@media (max-width:1024px){ body.sheet-calc::after{ display:none; } }

/* the blackout: paper-at-low-alpha instead of ink-at-low-alpha, exactly as the
   answer sheet under the course pages inverts itself */
:root[data-room="dark"] body.sheet-calc::before{
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34.1675' height='34.1675'%3E%3Cpath d='M.5 0V34.1675' fill='none' stroke='%23faf8f7' stroke-opacity='.055'/%3E%3C/svg%3E");
}
:root[data-room="dark"] body.sheet-calc::after{
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='300'%3E%3Cpath d='M4 296 L8.2 293.2 L12.3 290.4 L16.5 287.6 L20.7 284.8 L24.9 279.2 L29 273.6 L33.2 268 L37.4 262.4 L41.6 256.8 L45.7 251.2 L49.9 245.6 L54.1 240 L58.3 231.6 L62.4 226 L66.6 220.4 L70.8 214.8 L75 209.2 L79.1 200.8 L83.3 195.2 L87.5 189.6 L91.7 181.2 L95.8 175.6 L100 167.2 L104.2 161.6 L108.3 153.2 L112.5 147.6 L116.7 142 L120.9 133.6 L125 128 L129.2 122.4 L133.4 116.8 L137.6 108.4 L141.7 102.8 L145.9 94.4 L150.1 88.8 L154.3 83.2 L158.4 74.8 L162.6 69.2 L166.8 60.8 L171 55.2 L175.1 49.6 L179.3 41.2 L183.5 35.6 L187.7 27.2 L191.8 21.6 L196 16' fill='none' stroke='%23faf8f7' stroke-opacity='.21' stroke-width='1.3'/%3E%3Cpath d='M2 296 h4 M4 294 v4 M18.7 284.8 h4 M20.7 282.8 v4 M35.4 262.4 h4 M37.4 260.4 v4 M52.1 240 h4 M54.1 238 v4 M68.8 214.8 h4 M70.8 212.8 v4 M85.5 189.6 h4 M87.5 187.6 v4 M102.2 161.6 h4 M104.2 159.6 v4 M118.9 133.6 h4 M120.9 131.6 v4 M135.6 108.4 h4 M137.6 106.4 v4 M152.3 83.2 h4 M154.3 81.2 v4 M169 55.2 h4 M171 53.2 v4 M185.7 27.2 h4 M187.7 25.2 v4 M194 16 h4 M196 14 v4' fill='none' stroke='%23faf8f7' stroke-opacity='.17'/%3E%3Cpath d='M4 16 V296 H196 M4 296 v5 M45.7 296 v5 M87.5 296 v5 M129.2 296 v5 M171 296 v5 M196 296 v5 M4 296 h-4 M4 226 h-4 M4 156 h-4 M4 86 h-4 M4 16 h-4' fill='none' stroke='%23faf8f7' stroke-opacity='.14'/%3E%3Cpath d='M91.7 296 V181.2 H4' fill='none' stroke='%23faf8f7' stroke-opacity='.12' stroke-dasharray='3 3'/%3E%3Cpath d='M91.7 181.2 m-2.6 0 a2.6 2.6 0 1 0 5.2 0 a2.6 2.6 0 1 0 -5.2 0' fill='none' stroke='%23faf8f7' stroke-opacity='.17'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='120'%3E%3Cpath d='M4 106.5 C8 105.6 19.2 107.4 27.8 101 C36.5 94.6 49.8 75.3 55.8 68 C61.8 60.7 61.2 58.8 63.8 57 C66.5 55.2 69.2 58.8 71.8 57 C74.5 55.2 77.2 49.7 79.8 46 C82.5 42.3 85.2 36.8 87.8 35 C90.5 33.2 93.2 35 95.8 35 C98.5 35 101.2 35 103.8 35 C106.5 35 109.2 35 111.8 35 C114.5 35 117.2 35 119.8 35 C122.5 35 125.2 36.8 127.8 35 C130.5 33.2 133.2 24 135.8 24 C138.5 24 141.2 31.3 143.8 35 C146.5 38.7 149.2 42.3 151.8 46 C154.5 49.7 157.2 51.5 159.8 57 C162.5 62.5 163.8 71.6 167.8 79 C171.9 86.4 179.3 96.3 184 101.1 C188.7 106 194 106.8 196 107.9' fill='none' stroke='%23faf8f7' stroke-opacity='.20' stroke-width='1.3'/%3E%3Cpath d='M4 112 H196 M4 112 v5 M52 112 v5 M100 112 v5 M148 112 v5 M196 112 v5' fill='none' stroke='%23faf8f7' stroke-opacity='.14'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='240'%3E%3Cpath d='M4 230 L12.7 230 M14.5 222.4 L21.5 212.7 M23.2 212.4 L30.2 202.6 M31.9 202.3 L38.9 192.6 M40.7 192.2 L47.6 182.1 M49.4 181.8 L56.4 172 M58.1 171.7 L65.1 162 M66.8 161.6 L73.8 151.5 M75.6 151.2 L82.5 141.4 M84.3 141.1 L91.3 131.4 M93 131 L100 120.9 M101.7 120.6 L108.7 110.8 M110.5 110.5 L117.5 100.8 M119.2 100.4 L126.2 90.7 M127.9 90.3 L134.9 80.2 M136.7 79.9 L143.6 70.2 M145.4 69.8 L152.4 60.1 M154.1 59.7 L161.1 49.6 M162.8 49.3 L169.8 39.6 M171.6 39.2 L178.5 28 M180.3 27.7 L185.5 15.8 M187.3 14 L196 14' fill='none' stroke='%23faf8f7' stroke-opacity='.20' stroke-width='1.3'/%3E%3Cpath d='M12.5 222.4 h4 M14.5 220.4 v4 M47.4 181.8 h4 M49.4 179.8 v4 M82.3 141.1 h4 M84.3 139.1 v4 M117.2 100.4 h4 M119.2 98.4 v4 M152.1 59.7 h4 M154.1 57.7 v4' fill='none' stroke='%23faf8f7' stroke-opacity='.16'/%3E%3Cpath d='M4 14 V230 H196 M12.7 230 v5 M56.4 230 v5 M100 230 v5 M143.6 230 v5 M187.3 230 v5 M4 230 h-4 M4 176 h-4 M4 122 h-4 M4 68 h-4 M4 14 h-4' fill='none' stroke='%23faf8f7' stroke-opacity='.14'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='150'%3E%3Cpath d='M4 140 L7.9 138.7 L11.8 137.4 L15.7 136.1 L19.6 134.8 L23.5 133.5 L27.5 132.2 L31.4 130.9 L35.3 129.6 L39.2 128.3 L43.1 127 L47 124.4 L50.9 121.8 L54.8 117.9 L58.7 115.3 L62.6 112.7 L66.5 110.1 L70.5 106.2 L74.4 103.6 L78.3 99.7 L82.2 97.1 L86.1 93.2 L90 90.6 L93.9 86.7 L97.8 84.1 L101.7 80.2 L105.6 77.6 L109.5 75 L113.5 71.1 L117.4 68.5 L121.3 65.9 L125.2 62 L129.1 59.4 L133 55.5 L136.9 52.9 L140.8 49 L144.7 45.1 L148.6 39.9 L152.5 36 L156.5 32.1 L160.4 26.9 L164.3 23 L168.2 19.1 L172.1 15.2 L176 10' fill='none' stroke='%23faf8f7' stroke-opacity='.20' stroke-width='1.3'/%3E%3Cpath d='M2 140 h4 M4 138 v4 M21.5 133.5 h4 M23.5 131.5 v4 M41.1 127 h4 M43.1 125 v4 M60.6 112.7 h4 M62.6 110.7 v4 M80.2 97.1 h4 M82.2 95.1 v4 M99.7 80.2 h4 M101.7 78.2 v4 M119.3 65.9 h4 M121.3 63.9 v4 M138.8 49 h4 M140.8 47 v4 M158.4 26.9 h4 M160.4 24.9 v4 M174 10 h4 M176 8 v4' fill='none' stroke='%23faf8f7' stroke-opacity='.16'/%3E%3Cpath d='M4 10 V140 H176 M4 140 v5 M47 140 v5 M90 140 v5 M133 140 v5 M176 140 v5 M4 140 h-4 M4 107.5 h-4 M4 75 h-4 M4 42.5 h-4 M4 10 h-4' fill='none' stroke='%23faf8f7' stroke-opacity='.14'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='834' height='14'%3E%3Cpath d='M7 0 V14 M0 7 H14 M3 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 M827 0 V14 M820 7 H834 M823 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0' fill='none' stroke='%23faf8f7' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='834' height='14'%3E%3Cpath d='M7 0 V14 M0 7 H14 M3 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 M827 0 V14 M820 7 H834 M823 7 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0' fill='none' stroke='%23faf8f7' stroke-opacity='.13'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='273.34' height='273.34'%3E%3Cpath d='M.5 0V273.34' fill='none' stroke='%23faf8f7' stroke-opacity='.15'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='273.34' height='273.34'%3E%3Cpath d='M0 .5H273.34' fill='none' stroke='%23faf8f7' stroke-opacity='.12'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34.1675' height='34.1675'%3E%3Cpath d='M0 .5H34.1675' fill='none' stroke='%23faf8f7' stroke-opacity='.055'/%3E%3C/svg%3E");
}


/* ————————————————————————————————————————————————————————————
   THE SHELL, PORTED FROM room.css

   The register head, the ask and the colophon are already drawn — the
   exam-rooms skin owns them. calc.html uses the same three, so the rules come
   here by hand rather than by <link>: linking a second page-family's stylesheet
   would drag in the register, the map, the spread and the pins, none of which
   this page has any markup for. Copied, not re-invented; if room.css's version
   moves, this one has to be moved with it.

   Three deviations, all belonging to THE FOOT REGISTER below and argued there:
   the ask has no fill and no lift; the ask and the colophon are ruled in
   --rail-line rather than --line; and their vertical margins are this page's
   own. Everything else is room.css's, unchanged. A room sheet's colophon stands
   alone under a photograph and a hairline is enough to fence it; here it is the
   third row of a ruled register and has to be drawn in the register's ink.
   ———————————————————————————————————————————————————————————— */

/* ——— the head ——— */
.reg-head{
  margin: 24px 0 0; padding-bottom: clamp(16px, 2.4vw, 24px);
  border-bottom: 1px solid var(--line);
}
/* ——— the title as a specimen ———
   The sheet's own convention, stated at the ask and now at the door: filled
   ink is a value that has been measured, a hollow stroke is one that hasn't.
   «علامتك» opens hollow — traced in the accent but not yet inked — and the
   instrument below is what fills it in: the first solid accent on the page
   is the computed score. The word sits on lettering guides, drawn the way
   this sheet draws every figure (ink once, dimmed once), running the full
   measure like the ruled sheet they came from; through the hollow letters
   the guides stay visible, which is what tracing on a ruled sheet looks
   like. Painted at z-index:-1 so they pass BEHIND the inked word — pseudo
   boxes are positioned and would otherwise paint over their own element's
   text. Where text-stroke is unsupported the word simply stays solid accent:
   the old title, nothing broken. */
.reg-title{
  margin:0; font-family:'Baloo Bhaijaan 2', sans-serif; font-weight:800;
  font-size: clamp(2rem, 1.4rem + 3.4vw, 3.7rem); line-height:1.3;
  letter-spacing:-.3px; color: var(--fg);
  position:relative;
}
.reg-title .hl{ color: var(--accent); }
.reg-title::before, .reg-title::after{
  content:''; position:absolute; inset-inline:0; z-index:-1; pointer-events:none;
  border-top:1px solid var(--fg);
}
.reg-title::before{ bottom:.37em; opacity:.26; }                      /* the baseline */
.reg-title::after{ top:.52em; opacity:.14; border-top-style:dashed; } /* the waist guide */
@supports (-webkit-text-stroke: 1px black){
  .reg-title .t-trace{
    -webkit-text-stroke: max(.036em, 1.5px) var(--accent);
    -webkit-text-fill-color: transparent;
  }
}
.reg-lede{
  margin: 12px 0 0; max-width: 34em;
  font-size: clamp(1rem, .96rem + .35vw, 1.14rem); line-height:1.85; color: var(--fg-soft);
}

/* ——— the ask ——— */
.reg-ask{
  margin: 20px 0 0; padding: clamp(20px, 3vw, 28px);
  border: 1px solid var(--rail-line);
  scroll-margin-top: clamp(18px, 4vw, 44px);
}
.reg-ask h2{
  margin:0; font-family:'Baloo Bhaijaan 2', sans-serif; font-weight:800;
  font-size: clamp(1.15rem, 1rem + .7vw, 1.5rem); line-height:1.5; color: var(--fg);
}
.reg-ask p{ margin: 8px 0 16px; max-width: 46em; font-size:.95rem; line-height:1.85; }
.reg-ask .btn{ text-decoration:none; }

/* ——— the colophon ———
   Where a drawing has always kept its administrative facts, and where this page
   keeps the two that decide whether the answer above is still true: which
   tables, and until when. */
.title-block{
  margin: 20px 0 0; padding:0; display:grid;
  grid-template-columns: minmax(0,1.7fr) repeat(3, minmax(0,1fr));
  border: 1px solid var(--rail-line);
}
.title-block > div{ padding: 11px 15px 13px; border-inline-start: 1px solid var(--rail-line); }
.title-block > div:first-child{ border-inline-start:0; }
.title-block dt{ margin:0; font-size:.71rem; line-height:1.5; color: var(--fg-mute); }
.title-block dd{ margin:4px 0 0; font-size:.85rem; line-height:1.6; color: var(--fg-soft); }
@media (max-width: 760px){
  .title-block{ grid-template-columns: 1fr 1fr; }
  .title-block > div:nth-child(odd){ border-inline-start:0; }
  .title-block > div:nth-child(n+3){ border-top: 1px solid var(--rail-line); }
}
@media (max-width: 460px){
  .title-block{ grid-template-columns: 1fr; }
  .title-block > div{ border-inline-start:0; border-top:1px solid var(--rail-line); }
  .title-block > div:first-child{ border-top:0; }
}


/* ————————————————————————————————————————————————————————————
   THE INSTRUMENT

   No markup yet — it arrives with the script. What is settled here is that it
   is a form printed on the worksheet, not a widget dropped onto it: a row per
   domain, the field where the number goes, the score where the answer goes,
   and a rule under each row. The only thing that moves is a number fading as
   it is replaced.
   ———————————————————————————————————————————————————————————— */
.inst{ margin:2.5em 0 3.5em; }
/* two choosers, two paper idioms — both centered on the sheet's axis.

   .inst-test picks the EXAM, and it is drawn as what the word «tab» has
   always meant: two folder tabs standing on a rule that runs the full
   measure. The open one rises a step, takes the card surface, and its own
   background swallows the rule beneath it — the tab opens INTO the sheet
   it labels. The closed one stays low and mute with the rule passing under
   it. The 1px overlap (margin-bottom:-1px) is the whole mechanism: open
   bottoms are made, not styled. */
.inst-test{
  display:flex; justify-content:center; align-items:flex-end; gap:8px;
  border-bottom:1px solid var(--line); margin-bottom:1.8em;
}
.inst-test label{
  border:1px solid var(--line); border-bottom:0; border-radius:11px 11px 0 0;
  margin-bottom:-1px; padding:8px 22px 9px; cursor:pointer;
  color:var(--fg-mute); font-size:.92em; font-weight:600; background:transparent;
  transition: color .18s var(--out), background-color .18s var(--out), padding-top .18s var(--out);
}
.inst-test label:has(input:checked){
  background:var(--card); color:var(--fg); padding-top:12px;
}
/* .inst-mode picks how the numbers arrive, and it is the other thing paper
   does with an either/or: print both, circle the one that applies. Plain
   printed options with a quiet «أو» between them, and the chosen one wears
   a drawn ink ellipse — inked on in half a second when the choice is made,
   simply present when motion is off (the keyframe names only its from).
   The viewBox ratio sits close to the label's own, so the stretch is nearly
   uniform and a user-unit stroke lands at hairline weight — non-scaling
   stroke plus a normalized dash is exactly the combination Chrome renders
   with a seam spike, so neither is used. The dash guard runs one unit past
   the path (a dash equal to pathLength shows a sliver at the seam), and the
   hidden offset sits one MORE past it: parked exactly on the pattern
   boundary, the seam still prints a dot. */
.inst-mode{
  display:flex; justify-content:center; flex-wrap:wrap; gap:6px 44px;
  margin-bottom:1.6em;
}
.inst-mode label{
  position:relative; padding:8px 14px; cursor:pointer;
  color:var(--fg-mute); font-size:.92em;
  transition: color .18s var(--out);
}
.inst-mode label:has(input:checked){ color:var(--fg); }
.inst-mode label + label::before{
  content:'أو'; position:absolute; inset-inline-start:-31px; top:50%;
  translate:0 -50%; color:var(--fg-mute); font-size:.8em; pointer-events:none;
}
.inst-mode .ring{
  position:absolute; inset:0; width:100%; height:100%;
  overflow:visible; pointer-events:none;
}
.inst-mode .ring ellipse{
  fill:none; stroke:var(--fg); stroke-width:.75; opacity:.55;
  stroke-dasharray:101; stroke-dashoffset:102;
}
.inst-mode label:has(input:checked) .ring ellipse{
  stroke-dashoffset:0;
  animation: ring-draw .45s var(--out);
}
@keyframes ring-draw{ from{ stroke-dashoffset:102; } }
/* the radio itself is invisible, so the focus ring has to be drawn on the
   label it hides behind — without this a keyboard user tabbing into the
   first control on the page gets no focus at all */
.inst-test label:has(input:focus-visible){ outline:2px solid var(--accent); outline-offset:2px; }
.inst-mode label:has(input:focus-visible){ outline:2px solid var(--accent); outline-offset:-2px; border-radius:999px; }
.inst-test input, .inst-mode input{ position:absolute; opacity:0; pointer-events:none; }
@media (prefers-reduced-motion: reduce){
  .inst-test label, .inst-mode label{ transition:none; }
  .pct-dots circle{ transition:none; }
}
@media (max-width:480px){
  .inst-test label{ padding-inline:14px; }
  .inst-mode{ gap:2px 30px; }
  .inst-mode label + label::before{ inset-inline-start:-24px; }
}
/* one panel at a time; the section's data-test is written by the script and
   synced at init exactly like data-mode */
.inst[data-test="yael"] .panel-psy{ display:none; }
.inst[data-test="psy"] .panel-yael{ display:none; }
/* yael's rail has no band — the parked marker hides by its own parked cx */
#scale-pt-y[cx="-10"]{ display:none; }
.inst-rows{ display:grid; gap:2px; }
/* the figure takes the row's slack: every other column is sized by what it
   holds — the label, the field unit, the toggle, the score — and the nomogram
   is the one element that reads better at every extra millimetre */
.inst-row{
  display:grid; grid-template-columns: 5.2em auto auto minmax(140px,1fr) auto;
  align-items:center; gap:12px; padding:12px 0; border-bottom:1px solid var(--line);
}
.inst-name{ color:var(--fg); font-weight:600; }
/* the field is one LTR unit — a grade reads «▯/46», blank then slash then
   total, and that order does not flip with the page (owner-settled,
   2026-07-30). flex-end keeps the unit against the label's side of its cell
   rather than drifting to the far edge. */
.inst-field{ display:flex; align-items:baseline; gap:6px; direction:ltr; justify-content:flex-end; }
/* Rubik and `direction:ltr`: the only face in the house drawn for digits, and a
   number typed into an RTL page is still typed left to right */
.inst-field input{
  width:5.5em; font:500 1.25em Rubik, sans-serif; font-variant-numeric:tabular-nums;
  color:var(--fg); background:var(--card); border:1px solid var(--line); border-radius:10px;
  padding:8px 12px; text-align:center; direction:ltr;
}
.inst-field input:focus{ outline:2px solid var(--accent); outline-offset:1px; border-color:transparent; }
.inst-max{ color:var(--fg-mute); font-size:.9em; }
.inst-ch{ display:flex; gap:4px; font-size:.82em; color:var(--fg-mute); }
.inst-ch label{ border:1px solid var(--line); border-radius:999px; padding:3px 10px; cursor:pointer; }
.inst-ch label:has(input:checked){ color:var(--fg); border-color:var(--fg-mute); }
.inst-ch label:has(input:focus-visible){ outline:2px solid var(--accent); outline-offset:1px; }
.inst-ch input{ position:absolute; opacity:0; pointer-events:none; }
.inst-score{
  font:500 1.3em Rubik,sans-serif; font-variant-numeric:tabular-nums; color:var(--fg);
  min-width:2.4em; text-align:center;
}
/* the row's figure is a nomogram — two parallel scales and a tie between
   them, which is what a paper calculator IS. Count on the lower scale (0 to
   the row's ceiling, so the graduation is quarters, not numbers), score on
   the upper (50–150, tens), and the tie is the table lookup drawn: its slope
   is the conversion. Empty state is the two scales alone.
   It is also the row's third control: pointer down and drag scrubs the count
   under the finger through the same input path typing uses. cursor and
   touch-action carry the affordance — pan-y leaves a vertical thumb to the
   page and keeps a horizontal one. The field stays the accessible control;
   this surface is pointer-only and aria-hidden.
   LTR inside, like every rail on this page. */
.row-plot{
  display:flex; align-items:center; direction:ltr;
  cursor:ew-resize; touch-action:pan-y; user-select:none; -webkit-user-select:none;
}
/* full ink at a declared opacity, not soft ink at a doubled one: --fg-soft
   carries its own alpha in the dark room, so a stroke at `currentColor` came out
   a fifth weaker there than here for the same number. Every figure on this page
   is drawn in the sheet's ink and dimmed once, in one place. */
.row-plot svg{
  display:block; width:100%; height:auto; aspect-ratio:200 / 24; overflow:visible;
  color:var(--fg);
}
/* parked off-rail rather than removed, and hidden by the parked cx itself —
   the same tell the big rail's marker uses. The tie parks as a lone moveto,
   which draws nothing on its own. Neither TRAVELS to its position: a plotted
   figure is put where it belongs; you do not watch it get there. */
.rp-pt[cx="-10"]{ display:none; }
.inst-note{ color:var(--fg-mute); font-size:.85em; margin:.8em 0 0; }
/* entering a domain score directly makes the raw-count machinery meaningless —
   the chapter count, the ceiling, the converted score and its plot all go.
   Scoped to the psychometric panel: data-mode lives on .inst but the mode is
   psy-only state, and unscoped these rules followed a stale «score» across
   the tab switch and swallowed yael's own count field and toggle. */
.inst[data-mode="score"] .panel-psy .inst-ch, .inst[data-mode="score"] .panel-psy .inst-max{ display:none; }
.inst[data-mode="score"] .panel-psy .inst-score,
.inst[data-mode="score"] .panel-psy .row-plot{ visibility:hidden; }
.inst[data-mode="raw"] .panel-psy .in-sc{ display:none; }
.inst[data-mode="score"] .panel-psy .in-raw{ display:none; }

/* ——— results: the report's summary lines ———
   Three weighted scores, and the one NITE leads with set at display scale in
   the page's one accent. Everything else on this sheet is ink. */
.inst-out{ margin-top:2.2em; display:grid; grid-template-columns:1fr; gap:0; }
.res{
  display:grid; grid-template-columns:1fr auto; align-items:baseline;
  gap:6px 16px; padding:14px 0; border-bottom:1px solid var(--line);
}
.res-name{ color:var(--fg-soft); }
.res-g{ font:500 1.6em Rubik,sans-serif; font-variant-numeric:tabular-nums; color:var(--fg); }
.res-w, .res-band{ color:var(--fg-mute); font-size:.88em; }
/* the two explicit rows are for the construction line, not for the text: the
   line is an abspos grid child, and only a grid area bounded by lines that
   exist can hold it. Declaring the first rows explicit makes line 3 nameable
   without moving a single item — every row here was auto-sized already. */
.res-multi{
  border-top:2px solid var(--fg); padding-block:20px;
  position:relative; grid-template-rows:auto auto;
}
.res-multi .res-g{ font-size:2.6em; color:var(--accent); line-height:1.2; }
/* the percentile, said AND drawn: ten dots, one per decile of the field,
   inked up to yours from the right — the way this page reads. The figure
   itself is the line's strongest ink; the citation tail steps back to a
   whisper. The dots tween their fill, so a moving estimate slides through
   the population instead of teleporting. */
.res-pct{
  grid-column:1 / -1; color:var(--fg-soft); font-size:.95em; margin:0;
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
}
.pct-dots{ width:78px; height:8px; flex:none; overflow:visible; }
.pct-dots circle{ fill:var(--fg); fill-opacity:.16; transition:fill-opacity .3s var(--out); }
.pct-dots circle.on{ fill-opacity:.6; }
.pct-n{ color:var(--fg); font-weight:600; font-size:1.05em; }
.pct-src{ color:var(--fg-mute); }
/* the printed derivative: a line of priced deltas under the percentile, a
   step quieter than it — and the pair where the five buy most keeps the
   full ink, so the eye lands on the answer, not the arithmetic */
.res-gain{ grid-column:1 / -1; color:var(--fg-mute); font-size:.88em; margin:0; }
.res-gain .latin{ color:var(--fg-soft); }
/* a domain and its price are one word: the line breaks between pairs or not at all */
.gain-pair{ white-space:nowrap; }
.gain-pair.gain-top{ color:var(--fg-soft); }
.gain-pair.gain-top .latin{ color:var(--fg); font-weight:600; }
.inst[data-mode="score"] .res-gain{ display:none; }
.res-cta{ grid-column:1 / -1; color:var(--fg-mute); font-size:.92em; margin:0; }
.res-cta a{ color:var(--accent); }
/* the 200–800 rail. Held at the viewBox's own ratio rather than a fixed height,
   because a fixed height scaled x by width/600 and y by 1, and the round marker
   came out an ellipse whose eccentricity flipped sides at the width where the
   rail passes 600px. At this ratio the scale is uniform, so the point stays a
   point at every measure — which also leaves the markup's
   `preserveAspectRatio="none"` inert: it and the default agree while the box
   keeps this ratio. It stays as the floor if the box is ever stretched, since a
   linear map from score to x is the one thing the rail cannot lose.
   overflow stays visible: a score of 200 or 800 puts the marker on the rail's
   end, and half a marker is worse than one that overhangs. */
.scale{
  grid-column:1 / -1; width:100%; aspect-ratio:600 / 26; height:auto;
  overflow:visible; direction:ltr; color:var(--fg); /* the ink, see .row-plot svg */
}
/* the fine graduation is the first thing to go when the rail gets short. Held to
   the same ratio, a 350px rail is 15px tall and its minor ticks are 2px of
   hairline 14px apart — under the width where that reads as a graduation it
   reads as dirt, so below 700px the rail is graduated at the five numbers it is
   actually read at. Coarser at a smaller scale is what a drawn scale does. */
@media (max-width:700px){ .scale-fine{ display:none; } }
/* before the first number is typed the script parks the marker off-scale rather
   than removing it — and an unclipped rail duly shows it, an accent dot floating
   in the left margin of an otherwise blank result. The parked band is the tell.
   The sibling-composition rings park by their own cx, like the row points. */
#scale-band[width="0"] + #scale-pt{ display:none; }
.scale-alt[cx="-10"]{ display:none; }

/* ——— the construction line ———
   One dashed stroke per recompute, ink and never accent, running from the
   block's top rule down onto the marker: the moment the measurement is taken.
   It is two boxes because it crosses two coordinate systems — this half is CSS
   over the text rows, the other half (.scale-cons) is inside the rail's own
   viewBox — and they are collinear at the same x, so the seam is not a seam.
   `left` is physical on purpose: the rail is LTR inside an RTL page, so 0% is
   200 and stays 200 whichever way the page runs. The two negative insets reach
   past the block's own 20px padding to the rule itself and past the grid's 6px
   row gap to the rail's top edge: a construction line that stops 22px short of
   what it is constructing from is a dash, not a connection.
   clip-path is declared here, not only in the keyframes: inset() does not
   interpolate against `none`, so the resting state has to be an inset too. */
.res-cons{
  position:absolute; grid-column:1 / -1; top:-20px; bottom:-6px; width:0;
  border-left:1px dashed var(--fg); opacity:.32; pointer-events:none;
  clip-path:inset(0 0 0 0);
}
.panel-psy .res-cons{ grid-row:1 / 3; }   /* the name row, then weighted+band */
.panel-yael .res-cons{ grid-row:1 / 2; }  /* yael's block has one text row */
.panel-yael .res-multi{ grid-template-rows:auto; }

/* ——— what moves ———
   Four movements, none decorative: the construction line draws in, the scores
   settle, a row's marker slides along its rail, and a panel being shown fades
   rather than appearing mid-page. Every keyframe list names only its `from`, so
   the resting state IS the element's own — which is what makes course.css's
   global reduced-motion kill (`animation:none !important` on everything) leave
   a fully drawn, instant instrument instead of an invisible one. Nothing here
   has to finish in order to be read. */
@keyframes calc-draw{ from{ clip-path:inset(0 0 100% 0); } }
@keyframes calc-settle{ from{ opacity:0; transform:translateY(-3px); } }
@keyframes calc-fade{ from{ opacity:0; } }
/* the script inks a figure only when its VALUE moved, so a three-digit entry
   draws once when it lands rather than three times on the way */
.res-multi.ink .res-cons{ animation:calc-draw .35s var(--out); }
.res-multi.ink .scale-cons{ animation:calc-fade .35s var(--out); }
.res-multi.ink .res-g, .res-g.ink, .inst-score.ink{ animation:calc-settle .2s var(--out); }
/* the two advice lines arrive and switch the same way: they settle in when
   their VALUE moves — never per keystroke, never mid-scrub (the ink gate) */
.res-pct.ink, .res-gain.ink{ animation:calc-settle .3s var(--out); }
.inst[data-test="psy"] .panel-psy,
.inst[data-test="yael"] .panel-yael,
.inst[data-mode="raw"] .in-raw,
.inst[data-mode="score"] .in-sc{ animation:calc-fade .15s var(--out); }

/* the narrow row reads as three register lines: the domain and its score,
   then the controls, then the figure at full measure — the one element that
   gains from every millimetre a phone can give it */
@media (max-width:700px){
  .inst-row{ grid-template-columns:auto 1fr; }
  .inst-name{ grid-column:1; grid-row:1; }
  .inst-score{ grid-column:2; grid-row:1; justify-self:end; }
  .inst-field{ grid-column:1; grid-row:2; }
  .inst-ch{ grid-column:2; grid-row:2; justify-self:end; }
  .row-plot{ grid-column:1 / -1; grid-row:3; margin-top:4px; }
}


/* ————————————————————————————————————————————————————————————
   THE FOOT REGISTER — the revision note, the ask, the colophon

   Everything above this point is drawn: the paper is ruled, the margins carry
   true plotted figures, the results are read off a graduated rail with a
   dimension on it. The two blocks at the foot were the last things on the sheet
   that were not — white, rounded, lifted, imported card idiom. A card is a thing
   sitting ON paper; a worksheet has no cards on it, it has BLOCKS drawn on it.

   So both are re-drawn in the sheet's own hand and the colophon joins them:
   three ruled blocks, hairline frame in --line, square corners, internal
   dividers where a real block divides, and no fill — the graph paper runs
   straight through them, exactly as it runs through the instrument's rows. That
   also settles --lift, which was the odd one out in two ways: it only ever
   existed in daylight (course.css sets it to `none` in the blackout), so the
   two rooms disagreed about whether these blocks were objects. Now neither
   room lifts them and both rooms agree.

   The gaps say the same thing: 20px between the three, one 3.5em above them.
   Read as one thing at the foot of the sheet, set off from the instrument.

   THE INK, four steps, every one of them a token that already knows both rooms:

     --rail-line   every rule that DRAWS the register — the three frames, the
                   colophon's cells, the revision block's own divisions, the
                   diagram's boxes, the timeline and the dimension. It is the
                   course pages' rail, i.e. ink at a declared .145/.16, and it
                   is the lightest line on this page that actually reads on
                   daylight paper. --line, which the ask and the colophon used
                   to be framed in, does not: at #e7e5e4 on #f5f3f1 the frame
                   was two shades off invisible in daylight while reading
                   perfectly in the blackout, so the blocks existed in one room
                   and not the other.
     --fg @ .42    the dashed leader and its arrowhead. The sheet's rule about
                   figures — full ink at a declared opacity, never soft ink at a
                   doubled one — so it sits a step above the construction line
                   in the result block (.32), which is what a leader should do.
     --fg-mute     the annotation words: the timeline's dates, the dimension's
                   two labels. Same job as .title-block dt.
     --fg          the datum, 2px: the revision tick. Same weight and ink as the
                   rule over the result the page wants read first.

   And both drawings run the same way. Rightward is now, leftward is onward: the
   English domain leaves the box set to the left, the timeline runs from هلّق
   leftward to the change, the dimension runs from the grade you have to the one
   you want. One direction of travel across the whole register.

   And both drawings run the same way. Rightward is now, leftward is onward: the
   English domain leaves the box set to the left, the timeline runs from هلّق
   leftward to the change, the dimension runs from the grade you have to the one
   you want. One direction of travel across the whole register.
   ———————————————————————————————————————————————————————————— */
.pivot{ border:1px solid var(--rail-line); margin:3.5em 0 0; }
.pivot p{ margin:.5em 0; }

/* ——— the revision note ———
   A drawing that changes gets a revision block, and December 2026 IS a revision
   to this exam. So the aside is drafted as one: the flag in its own cell, the
   heading beside it, the description under the rule. The flag is the bare
   revision triangle and carries no number — the sheet keeps no revision
   numbering, and a made-up «1» inside it would be the only untrue mark on a
   page whose margins are generated from the engine's own tables. The heading
   next to it says which change; that is the label. */
.rev-head{
  display:grid; grid-template-columns: 44px minmax(0,1fr); align-items:center;
  border-bottom:1px solid var(--rail-line);
}
.rev-flag{ align-self:stretch; display:grid; place-items:center; color:var(--fg); }
.rev-flag svg{ display:block; width:22px; height:auto; }
/* the two blocks' headings are one size, a step under the page's own h1 — the
   ask's, which room.css already sets. The base h2 is larger and would have made
   the register's first row shout at its second. */
.rev-head h2{
  margin:0; padding:13px clamp(20px,3vw,28px) 15px;
  border-inline-start:1px solid var(--rail-line);
  font-family:'Baloo Bhaijaan 2', sans-serif; font-weight:800;
  font-size: clamp(1.15rem, 1rem + .7vw, 1.5rem); line-height:1.5; color: var(--fg);
}
/* the description cell sits on the same inset as the ask's copy, so the two
   blocks' text starts on one line down the sheet */
.rev-body{ padding: clamp(13px,1.9vw,17px) clamp(20px,3vw,28px) clamp(20px,3vw,26px); }

/* ——— the figure: what changed ———
   Two solid boxes and a dashed one. Dashed is the drawing convention for an edge
   that is not there, and the leader running out of it lands on أميرنت — which
   is deliberately NOT boxed, because it is not one of the exam's domains any
   more. The absence of a frame is the whole statement; a second frame around it,
   or a shoulder under it, would only soften that.
   The leader is the one thing in the figure that STRETCHES, and it has to be:
   the boxes are a set and pack tight, أميرنت is a destination and belongs at the
   far end, and the timeline underneath is graduated across the figure's whole
   width. With the leader fixed, the top row ran out less than half way and the
   two halves of one figure did not look measured against each other. Flexing it
   puts both rows on one span at every width, and a leader that gets longer as
   the sheet gets wider is saying the right thing anyway.
   It is a flexing CSS dash plus a fixed 8px arrowhead rather than one stretched
   SVG, because a stretched viewBox scales the arrowhead with the line and it
   stops being an arrowhead. The head points physically left: SVG geometry does
   not flip with direction, and this sheet is RTL at every width — room.css's
   pins settle the same question the same way. */
.rev-fig{ margin-top: clamp(18px,2.6vw,26px); }
.rev-what{
  display:flex; align-items:center; flex-wrap:wrap;
  gap:clamp(6px,1.2vw,10px);
}
.rev-box{
  border:1px solid var(--rail-line); padding:5px 9px 6px;
  font-size:.82rem; line-height:1.5; font-weight:500; color:var(--fg); white-space:nowrap;
}
.rev-box.is-out{ border-style:dashed; }
.rev-lead{
  flex:1 1 auto; min-width:34px; display:flex; align-items:center;
  color:var(--fg); opacity:.42;
}
.rev-lead::before{ content:''; flex:1 1 auto; border-top:1px dashed currentColor; }
.rev-lead svg{ flex:none; display:block; width:8px; height:12px; }
.rev-dest{ font-size:.82rem; line-height:1.5; font-weight:500; color:var(--fg); white-space:nowrap; }

/* ——— the figure: when ———
   A graduated rail with two ticks, read rightward-in. تشرين 2026 is the last
   sitting the tables above are stated to cover — the colophon two blocks down
   says the same in words — and the far end is the change, so the rail spans
   exactly the stretch of calendar this page can answer for. The heavy tick is
   the revision, in the same 2px --fg the result block uses for the one line
   it wants read first. */
.rev-when{
  margin-top:22px; padding-top:9px; border-top:1px solid var(--rail-line);
  display:grid; column-gap:10px;
  grid-template-columns: minmax(min-content,1fr) min-content;
}
.rev-t{
  position:relative; white-space:nowrap;
  font-size:.78rem; line-height:1.6; color:var(--fg-mute);
}
.rev-t::before{
  content:''; position:absolute; top:-9px; inset-inline-start:0;
  width:1px; height:7px; background:var(--fg-mute);
}
.rev-t:last-child{ justify-self:end; }
.rev-t:last-child::before{ inset-inline-start:auto; inset-inline-end:0; }
.rev-t.is-rev{ color:var(--fg); }
.rev-t.is-rev::before{ width:2px; height:9px; background:var(--fg); }

/* ——— the ask, dimensioned ———
   «بين علامتك وهدفك مسافة؟» is a dimension question, and the sheet already knows
   how to draw one: the result block brackets the official range with end ticks
   and a line. Here the terminators are the two points instead — filled ink for
   the grade that exists and has been measured, a hollow ring for the one being
   aimed at. room.css's map runs the same distinction (filled node = a sheet you
   can open, hollow = on the list), and the ring is the sheet's one accent spent
   as a LINE, which is what --accent is for. The unknown sits in the break in
   the dimension line, where a dimension has always carried its value.
   ::before and ::after are the run's first and last flex items and the «؟» is
   the anonymous one between them — two segments and a value, one element. */
.ask-dim{
  display:flex; align-items:center; gap:0;
  margin-bottom: clamp(16px,2.4vw,22px);
}
.ask-lab{ font-size:.8rem; line-height:1.6; color:var(--fg-mute); white-space:nowrap; }
.ask-lab:first-child{ padding-inline-end:9px; }
.ask-lab:last-child{ padding-inline-start:9px; }
.ask-mk{ flex:none; width:8px; height:8px; border-radius:50%; background:var(--fg); }
.ask-mk.is-goal{ width:11px; height:11px; background:none; border:1.5px solid var(--accent); }
.ask-run{
  flex:1 1 auto; display:flex; align-items:center; gap:9px;
  font-size:1.05rem; font-weight:500; line-height:1; color:var(--fg);
  position:relative;
}
.ask-run::before, .ask-run::after{ content:''; flex:1 1 auto; height:1px; background:var(--rail-line); }

/* ——— بريمو، perched ———
   The house owl, from the landing's hero rig, trimmed to what a worksheet
   can carry: no bubble, no acting, no roundel — just the bird. He stands on
   the dimension line on the علامتك side, toes over the rule, head tilted
   at the «؟»: an owl staring at the unknown points the reader's eye at
   exactly the gap this section asks about. The gaze is baked into the
   pupils' own translate, so nothing needs a script. Two movements only,
   both idle: a breath and a blink — every keyframe rests at its markup
   state, so the global reduced-motion kill leaves him perched, eyes open.
   `left` is physical: the ؟ sits at the run's center either way, and the
   measured side of this page's dimension is the right. The figure row
   makes headroom for him with padding, not overflow. */
.ask-dim{ padding-top: clamp(50px, 8vw, 68px); }
.ask-primo{
  position:absolute; left:calc(50% + 16px); bottom:calc(50% - 2px);
  width:clamp(56px, 8vw, 72px); pointer-events:none;
}
/* five idle movements on five unshared periods (4.6 / 5.5 / 8 / 9 / 13s),
   so the composite never visibly repeats: a breath that shifts his weight
   on the perch, a blink, the gaze cycle — the «؟», the goal ring, the
   reader, back to work — an ear flick, and once a round a small hop, feet
   briefly off the line. Every keyframe rests at the markup state, so the
   reduced-motion kill leaves him perched, eyes open, on the «؟». */
.ask-primo svg{
  display:block; width:100%; height:auto;
  transform-origin:50% 100%; animation:primo-hop 9s infinite;
}
@keyframes primo-hop{
  0%, 84%, 100%{ transform:translateY(0) scale(1, 1); }
  86.5%{ transform:translateY(1px) scale(1.05, .93); }
  89%  { transform:translateY(-7px) scale(.98, 1.05); }
  91.5%{ transform:translateY(0) scale(1.03, .96); }
  94%  { transform:translateY(0) scale(1, 1); }
}
.p-breathe{ transform-origin:60px 121px; animation:primo-breathe 4.6s ease-in-out infinite; }
@keyframes primo-breathe{
  0%, 100%{ transform:scale(1, 1) rotate(0deg); }
  28%{ transform:scale(1.015, 1.03) rotate(1.4deg); }
  50%{ transform:scale(1.02, 1.042) rotate(0deg); }
  72%{ transform:scale(1.012, 1.024) rotate(-1.4deg); }
}
.p-lid{ animation:primo-blink 5.5s infinite; }
@keyframes primo-blink{ 0%, 91%, 100%{ transform:translateY(0); } 93.5%, 96.5%{ transform:translateY(27px); } }
.p-pupil{ transform:translate(-2.3px, 2.6px); animation:primo-gaze 8s ease-in-out infinite; }
@keyframes primo-gaze{
  0%, 26%, 72%, 100%{ transform:translate(-2.3px, 2.6px); }
  33%, 44%{ transform:translate(-5px, .4px); }
  52%, 62%{ transform:translate(1.2px, -2.2px); }
}
.p-head{ transform-origin:60px 44px; transform:rotate(-4deg); animation:primo-look 8s ease-in-out infinite; }
@keyframes primo-look{
  0%, 26%, 72%, 100%{ transform:rotate(-4deg); }
  33%, 44%{ transform:rotate(-8.5deg); }
  52%, 62%{ transform:rotate(1.5deg); }
}
.p-ear-r{ transform-origin:97px 27px; animation:primo-ear 13s infinite; }
@keyframes primo-ear{
  0%, 55%, 61.5%, 100%{ transform:rotate(0deg); }
  56.5%{ transform:rotate(8deg); }
  58%  { transform:rotate(0deg); }
  59.5%{ transform:rotate(6deg); }
}
/* and the one cued movement: hover the WhatsApp button and he looks at it —
   the mascot pointing at the door this section wants opened */
.reg-ask:has(.btn:hover) .p-pupil{ animation:none; transform:translate(-4.8px, 3.6px); transition:transform .25s var(--out); }
.reg-ask:has(.btn:hover) .p-head{ animation:none; transform:rotate(-9deg); transition:transform .25s var(--out); }
