/* ===========================================================
   /ajman — Screen 05, `05-ajman.md`.

   ONE GROUND, END TO END (§2). Black from the statement to the
   authority sentence, one inverted white band at the close,
   and the footer's own black below it. Two switches, both on
   section boundaries. There is no forced paper panel here and
   there must not be one: the client wall is About's, where
   §1.5a is satisfied by the page rather than by an exception.

   Nothing is set on a photograph, because there is no
   photograph — so this page carries no contrast measurement
   over imagery at all. Every pair on it is already in §5:
   #FFFFFF on #000000 21:1 · #EDEDED 17.94:1 · #A6A6A6 8.63:1 ·
   #111111 on #FFFFFF 18.88:1.

   The two dark line values are not interchangeable (continuity
   §9): --color-hairline-dark (#333333, 1.66:1) may only
   separate text sections, and #595959 — --color-ink-secondary's
   hex — is what a line takes when it BOUNDS something or
   carries a state. The ledger's block rules use each for
   exactly one of those jobs.

   COLOUR IS STATED ON THIS PAGE, NEVER INHERITED. base.css
   colours every heading --color-ink and tokens.css lifts only
   .t-hero/.t-editorial/.t-h2/.t-h3 under .surface-dark — so
   .t-body-lg, and any bare element, computes #111111 on
   #000000 and disappears. Every rule below that sets type on
   black states its value.
   =========================================================== */

/* -----------------------------------------------------------
   1 · The statement (§4.1) — squat, and clear of the chrome
   ----------------------------------------------------------- */

/* Squat is specified, not incidental: the map must be at least partly in
   view at 1280×720. A full-viewport statement turns the page into a splash
   screen, which is the same rule Home's hero carries and for the same reason.

   The top padding CLEARS THE CHROME at every width. The trigger is fixed at
   the top inline-start — the same corner this statement starts in — and the
   plate hangs opposite it. Home's claim ran under the plate at 375, at 768
   and from ~1025 to ~1200px, and the collision was invisible to a box test
   because the box was 960px wide where the line was 870. Measured here
   against the rendered ink. */
.aj-statement {
  padding-block: var(--arrival-clearance) var(--gap-heading);
}

/* The ≤1023 restatement that used to sit here is GONE — the value now lives in
   --arrival-clearance (tokens-layout.css), which restates itself at the gap
   tokens' own breakpoint. Seven files carried this identical block; the whole
   point of P3 is that there is one place to change it. */

.aj-statement__line {
  margin: 0;
}

/* ⚠️ CURRENTLY UNUSED, AND KEPT ON PURPOSE (3 Aug). The supporting line was
   removed from `pages-src/ajman.html` because it repeated the site footer's
   own sentence; the copy sweep will give this page a line of its own and it
   lands back here. Deleting this rule in a tidy-up would silently reinstate
   the bug below the moment that happens.

   .t-body-lg is NOT in tokens.css's dark lift list, so this line would
   compute #111111 on #000000 and vanish. §4.1 fixes it at #EDEDED. */
.aj-statement__support {
  margin: var(--gap-block) 0 0;
  color: var(--color-on-dark-body);
}

/* -----------------------------------------------------------
   2 · The standing map and the ledger (§3.1) — one component
   ----------------------------------------------------------- */

.aj-standing {
  padding-block-end: var(--gap-section);
}

/* Work's standing-frame pattern with a map in the frame. 58% at the
   inline-start, the ledger takes the rest, and the map column is sticky —
   which is the only form in which this layout exists: a ~440px map beside a
   ~1,900px ledger in normal flow leaves ~1,400px of empty black. */
.aj-standing__grid {
  display: grid;
  grid-template-columns: 58% 1fr;
  column-gap: var(--gap-component);
  align-items: start;
}

/* The offset clears the fixed trigger, which occupies the top 64px of this
   same inline-start column. */
.aj-standing__map {
  position: sticky;
  inset-block-start: calc(var(--gap-component) + var(--gap-block));
}

/* The marks are TRUE 5px (E7.1), which is only true if the drawing does not
   scale under them. So the field takes one of four KNOWN widths — never a
   fluid one — and --mark-scale cancels each exactly (scale = 560 ÷ width):

     ≥1025px   480 wide, in the 58% column   → marks × 1.1667
     821–1024  400 wide, in the 58% column   → marks × 1.4
     640–820   560 wide, stacked (authored)  → marks × 1
     ≤639      320 wide, stacked             → marks × 1.75

   Home needed three because its map is always full width. This one is four
   because 821px is a real change of geometry, not a step in a scale: above
   it the map lives in a 58% column and below it the columns stack and the
   map takes the container. Each width is the largest that fits its band at
   the band's NARROWEST viewport — 480 against a 501.7px column at 1025,
   400 against 429.8px at 821 — so the svg never has to be clamped by
   max-inline-size, which would scale the marks with it. */
.aj-map {
  --mark-scale: 1.1667;

  /* THE COAST DRAWS FIRST, AND EVERY LATER STAGE IS MEASURED FROM IT.
     §3.5's choreography is coastline → marks → names, and this is the one
     value the sequence hangs on: the marks' stagger and the names' wipe both
     add it rather than restating a number of their own. Move it and the
     whole sequence moves together; that is the point. 1200ms is §3.5's own
     figure for the coastline, kept rather than re-judged, because the shape
     itself is still provisional and re-tuning a duration against artwork the
     client has not seen would be tuning against the wrong thing. */
  --coast-draw: 1200ms;

  /* A LABEL IS IN USER UNITS, SO THE 12px FLOOR IS NOT FREE (3 Aug).
     The svg is drawn on a 560-unit viewBox at four known widths, so a label
     authored once would render at four different sizes — and hard rule 9's
     12px floor is a RENDERED size, not an authored one. --label-size is
     therefore restated per width, exactly as --mark-scale is, and each value
     is the user-unit size that lands on 12px:

       width   scale        units   renders
       480px   0.857        14      12.0px    (desktop)
       400px   0.714        17      12.1px    (≤1024)
       560px   1.000        12      12.0px    (≤820, stacked)
       320px   0.571        21      —         labels OFF, see ≤639

     At 320px the floor demands 21 units, and ten names at 21 units on a
     560-unit field is the scatter this map was originally built without.
     The ledger directly beneath carries every district as real text, so
     nothing is lost by dropping them there — which is why the answer is to
     drop them rather than to shrink them below the floor.

     AUTHORED IN rem, WHICH IS NOT A DODGE OF RULE 2. Inside a viewBox a
     font-size computes to USER UNITS, so 0.875rem is 14 units, not 14
     screen pixels — and authoring it in rem rather than px means a reader
     who enlarges their root text enlarges these names too, which is the
     behaviour we want. The px column above therefore assumes the default
     16px root; above it, every label is larger than the floor, never
     smaller. */
  --label-size: 0.875rem;
}

.aj-map__svg {
  inline-size: 480px;
  max-inline-size: 100%;
  block-size: auto;
}

/* The names, in the drawing's own units. `text-anchor: middle` centres each
   on its cluster's centroid; the baseline drop is set in build/lib/ajman.js
   because it is measured against the mark's radius, which is geometry.
   Rest colour is the marks' own, so a name and its cluster read as one
   object rather than as a drawing with a caption. */
.aj-map__label {
  font-size: var(--label-size);
  font-weight: var(--fw-regular);
  text-anchor: middle;
  fill: var(--color-on-dark);
}

/* =========================================================================
   THE SHORELINE — rough, in house, 4 Aug 2026 (Mahesh), pending the client.

   Session VIII refused a TRUE coast and the reason was never difficulty: a
   real shoreline is what a reader measures a mark against, so under
   PLACEHOLDER centres every mark would have become a coordinate claim and
   the page would have been more wrong for being more real. This line makes
   no such claim — it is invented, the centres are invented, and board 12's
   footer already says so: "map geometry is invented and labelled as such."
   The shape, the clearances and what is deliberately absent (the creek, the
   Emirate outline) are in data/districts.json.

   NON-SCALING STROKE, AND THIS IS THE FAULT THE PAGE HAS ALREADY PAID FOR
   TWICE. The svg scales, so a stroke authored in user units is four
   different strokes at the field's four known widths — a 2-unit line renders
   1.71 / 2.40 / 2.00 / 3.50px. That is the identical arithmetic that cost
   --label-size a rebuild and that E7.1's true-5px mark exists to dodge.
   `vector-effect: non-scaling-stroke` makes 2px mean 2px everywhere, which
   is what §3.2 requires of the artwork layer in terms.

   IT IS SECONDARY, NOT WHITE. §3.3 tables the coastline at 2px #FFFFFF, and
   rendered at full white it read as the loudest thing on the field — the
   brief warned of exactly this ("a white 2px coast can out-shout the marks,
   which are the page's argument. Render it and look."). #A6A6A6 on #000000
   is 8.63:1, far above the 3:1 a structural line owes, and it puts the
   drawing back in the order the page argues in: marks first, ground second.
   The §3.3 value is the one to revisit when the commission's artwork lands.
   ========================================================================= */
.aj-coast {
  fill: none;
  stroke: var(--color-on-dark-secondary);
  stroke-width: 2;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* The finished coast is the SHIPPED state, exactly as the finished map is:
   with no script, and under reduced motion, the shore is already drawn.
   --coast-length is measured from the path at build time, so an edited
   shoreline re-times its own draw instead of being cut short by a stale
   literal. */
.aj-map--armed .aj-coast {
  stroke-dasharray: var(--coast-length);
  stroke-dashoffset: var(--coast-length);
}

.aj-map--drawing .aj-coast {
  stroke-dasharray: var(--coast-length);
  stroke-dashoffset: 0;
  transition: stroke-dashoffset var(--coast-draw) var(--ease-out);
}

.aj-mark {
  fill: var(--color-on-dark);
  transform: scale(var(--mark-scale));
  transform-box: fill-box;
  transform-origin: center;
}

/* The finished map is the SHIPPED state: with no script, and under reduced
   motion, every mark is already placed. js/ajman.js arms the animation by
   hiding the marks, then plays it once — so a broken script leaves a
   complete map rather than an empty field. */
.aj-map--armed .aj-mark {
  transform: scale(0);
}

/* 140ms per mark, 34ms apart — E7.3's own choreography, the same values
   Home's constellation and the menu overlay's dots run. */
.aj-map--drawing .aj-mark {
  transform: scale(var(--mark-scale));
  transition: transform 140ms ease-out;

  /* The sweep now FOLLOWS the shoreline (§3.5). The offset is added, never
     folded into a new literal, so the coast's duration stays the one place
     the sequence is timed from. */
  transition-delay: calc(var(--coast-draw) + var(--mark-index) * 34ms);
}

/* THE NAMES DRAW, AND THE EXCEPTION IS DECIDED (Mahesh, 4 Aug).

   `scripts.html`'s rule is that NO TEXT ANIMATES IN BY DEFAULT, and until
   today it had exactly one exception — the record page's neighbours marker
   (P2-b/H5-d). Mahesh extended it here rather than letting the board's
   "labels resolve" stage arrive as a build detail, because it is a change to
   what the rule means: the exception becomes a pattern rather than a one-off.

   It borrows that marker's MECHANISM exactly, and refuses the same thing it
   refused: the names WIPE ON from the inline-start edge — the menu overlay's
   own vocabulary — and there is no fade, no scale and no translate. MVRDV's
   scale+fade was declined on the record page because this file's motion
   language rules out decorative fades by name, and nothing about a map label
   reopens that.

   🔴 THE RESTING STATE IS AN EXPLICIT inset(), NOT THE ABSENCE OF A CLIP.
   `clip-path` does not interpolate between `inset(…)` and `none` — they are
   discrete values, so the wipe SNAPS and `getAnimations()` reports zero while
   the end state looks perfect. Both endpoints are inset() functions. This is
   the same trap the neighbours marker paid for once; it is written here as
   well because the next person to copy this will copy this file.

   The -12% bleed is not slack. It is a percentage rather than the marker's
   -4px because a label is inside a scaling viewBox — a px bleed would be four
   different bleeds at the field's four known widths, which is the identical
   fault --label-size and the stroke question already cost this page. A
   percentage resolves against the label's own box, so it is one value.

   THE DELAY IS DERIVED, NEVER TYPED. The names arrive after the last mark
   lands: the sweep's final mark starts at (count − 1) × 34ms and runs 140ms,
   so that sum IS the label stage's delay. `--mark-count` comes from the build
   with the marks themselves, so a 48th building moves this automatically —
   §7's rule that no layout on this page is keyed to a number, applied to
   time. A typed 1058ms would be correct today and silently wrong the day the
   data changes. */
.aj-map__label {
  clip-path: inset(-12%);
}

.aj-map--armed .aj-map__label {
  clip-path: inset(-12% 100% -12% -12%);
}

/* Physical insets, because clip-path has no logical form. RTL is restated
   rather than left to inherit a left-to-right wipe — Arabic names read the
   other way and a name that drew against its own direction would be the one
   piece of this page that did. */
[dir="rtl"] .aj-map--armed .aj-map__label {
  clip-path: inset(-12% -12% -12% 100%);
}

/* 🔴 THE RELEASE IS RESTATED WHEREVER THE ARM IS, AND THAT IS NOT SYMMETRY
   FOR ITS OWN SAKE. js/ajman.js ADDS --drawing and leaves --armed in place,
   so the two states are settled by the cascade rather than by which class is
   present — and the RTL arm above carries an attribute selector, which
   outranks a release written with classes alone. Restated only in the
   media query below, LTR resolved on source order and RTL stayed armed
   FOREVER: ten district names clipped to nothing on every Arabic reader's
   map, with the marks, the ledger and every assertion in p11/p12/sweep-ajman
   green, because each of those watches the LTR page.

   The neighbours marker this borrowed from does not have the fault and could
   not have: js/project.js REMOVES its armed class, so its release is the base
   rule and no restatement can outrank it. Copying a mechanism without copying
   the shape of its release is what put the two rules in a contest at all. */
.aj-map--drawing .aj-map__label,
[dir="rtl"] .aj-map--drawing .aj-map__label {
  clip-path: inset(-12%);
  transition: clip-path 380ms var(--ease-out);
  transition-delay: calc(var(--coast-draw) + (var(--mark-count) - 1) * 34ms + 140ms);
}

/* THE INTERACTION, AS OPTION B REWRITES §3.4. With no polygons the map
   cannot be the index, so the ledger is the control and the map answers:
   the current district's marks hold #FFFFFF while every other mark drops to
   #A6A6A6. Two measured tokens — the page's own rest-and-current grammar
   from §3.3, applied to the marks because Option B has no labels to carry
   it — and never opacity, which §9.16 prohibits.

   The value change is an ECHO. The signal itself is carried by the ledger
   block in weight and in a 2px rule, so nothing here depends on colour
   alone, and a mark stays a fact rather than becoming a control. */
[data-current] .aj-mark {
  fill: var(--color-on-dark-secondary);
}

[data-current] .aj-mark.is-current {
  fill: var(--color-on-dark);
}

/* The names take the same echo, so a current block does not leave its cluster
   dimmed under a name still at full white. #A6A6A6 on #000000 is 8.63:1 — a
   rest state, never an unreadable one. */
[data-current] .aj-map__label {
  fill: var(--color-on-dark-secondary);
}

[data-current] .aj-map__label.is-current {
  fill: var(--color-on-dark);
}

/* THE HIT REGIONS — ten targets, and E7 rule 3 is honoured rather than
   worked around. Rule 3 bars MARKS as hit targets on arithmetic: 47 marks at
   44×44px do not fit 375px. There are ten regions, not forty-seven, and the
   smallest renders 68.7px at the narrowest of the four widths (103.1 / 85.9 /
   120.2 / 68.7 at 480 / 400 / 560 / 320). A mark is still a fact; the region
   over it is the control.

   The geometry is a nearest-cluster partition built in build/lib/districts.js
   — the reasoning, and the measurement that ruled out padded boxes, is there.

   `fill: none` and `pointer-events: all` are set as ATTRIBUTES in the markup,
   not here, because they are what the element is rather than how it looks: a
   stylesheet that failed to load would otherwise leave ten opaque plates over
   the drawing. This rule adds only the pointer, which is the one thing that
   tells a mouse reader the field answers at all — the regions are invisible
   by construction and nothing else on the map advertises them. */
.aj-hit {
  cursor: pointer;
}

/* -----------------------------------------------------------
   3 · The ledger (§4.2) — the page's inventory
   ----------------------------------------------------------- */

/* Quiet ruled blocks. The #333333 hairline separates two text sections,
   which is the one thing 1.66:1 is permitted to do.

   The inline-start rule is transparent at rest and takes #595959 when the
   block is current — declared on every block so the current state changes a
   colour and never the layout. A border that appears on hover moves the
   text it is beside. */
.aj-block {
  border-inline-start: 2px solid transparent;
  padding-inline-start: var(--gap-block);
  transition: border-inline-start-color var(--dur-fast) var(--ease-out);
}

/* 48px between blocks, not 128. A component gap either side ran the ledger
   to 4,336px against the spec's own ~1,900px arithmetic, and it put barely
   two district blocks on a screen — which matters here more than it would
   on a list, because the map answers the block the reader is in and the
   answer is only legible if some of its neighbours are visible too. The
   hairline does the separating; the space only has to keep the blocks from
   touching it. */
.aj-block + .aj-block {
  margin-block-start: var(--gap-block);
  padding-block-start: var(--gap-block);
  border-block-start: 1px solid var(--color-hairline-dark);
}

/* 12px uppercase, weight 500, #A6A6A6 — a head, not a heading in the
   visual sense. NO COUNTS on any of them (§4.2): the distribution is
   6·6·5·4·2·1·1·1·1·1, so a count beside each head prints a list of five
   ones and the page announces its own thin tail. The rows are the count. */
.aj-block__head {
  margin: 0 0 var(--gap-block);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-on-dark-secondary);
  transition: color var(--dur-fast) var(--ease-out);
}

/* Current: the head lifts to #FFFFFF at weight 600 and the block's rule
   takes #595959 — value plus weight plus a structural line, which is E2's
   nav pattern and never colour alone. Focus drives it exactly as hover
   does, and every row is already a link, so this costs no tab stop.

   `.is-current` IS THE SAME STATE REACHED FROM THE OTHER END (4 Aug). The
   selection is now two-way: a pointer over a map region sets this class from
   js/ajman.js. It is listed beside :hover and :focus-within rather than given
   rules of its own so the block has ONE current appearance however it was
   selected — a second declaration is how a map-driven current and a
   ledger-driven one start looking different. The CSS pair stays first and
   stays load-bearing: it is what survives the script failing. */
.aj-block[data-district]:hover,
.aj-block[data-district]:focus-within,
.aj-block[data-district].is-current {
  border-inline-start-color: var(--color-ink-secondary);
}

.aj-block[data-district]:hover > .aj-block__head,
.aj-block[data-district]:focus-within > .aj-block__head,
.aj-block[data-district].is-current > .aj-block__head {
  font-weight: var(--fw-semibold);
  color: var(--color-on-dark);
}

.aj-block__rows {
  margin: 0;
  padding: 0;
  list-style: none;
}

.aj-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline);
  align-items: baseline;
  justify-content: space-between;
  padding-block: var(--pad-table-row);
}

.aj-row__name {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-on-dark);
  border-block-end: 1px solid transparent;
}

.aj-row__name:hover,
.aj-row__name:focus-visible {
  border-block-end-color: currentcolor;
}

.aj-row__name:focus-visible {
  outline: 2px solid var(--color-on-dark);
  outline-offset: 2px;
}

/* The E9 provenance label and the year. Both are RECORD SURFACE, which is
   the whole of E12's split: this page's display prose carries no quantity
   at all and the ledger carries every one the records hold. */
.aj-row__meta {
  font-size: var(--fs-metadata);
  line-height: var(--lh-metadata);
  color: var(--color-on-dark-secondary);
}

/* The middot recedes without either value becoming a signal — Home's own
   separator, matched rather than re-decided. */
.aj-sep {
  color: var(--color-ink-secondary);
}

/* -----------------------------------------------------------
   4 · The schools (§5) and the authority sentence (§6.1)
   ----------------------------------------------------------- */

.aj-schools,
.aj-authority {
  padding-block-end: var(--gap-section);
}

.aj-schools__line {
  margin: 0;
}

/* ~44ch: the authority sentence is long by construction — it names four
   bodies rather than counting them — so it runs at the editorial measure's
   sentence width rather than the display measure's short-line one. */
.aj-authority__line {
  margin: 0;
  max-inline-size: 44ch;
}

.aj-schools__support,
.aj-authority__support {
  margin: var(--gap-block) 0 0;
  max-inline-size: var(--measure-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-on-dark-body);
}

.aj-schools__route {
  margin: var(--gap-heading) 0 0;
}

.aj-link {
  display: inline-block;
  border-block-end: 1px solid currentcolor;
  padding-block-end: 2px;
  font-size: var(--fs-metadata);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--color-on-dark);
  transition: border-block-end-width var(--dur-fast) var(--ease-out);
}

.aj-link:hover,
.aj-link:focus-visible {
  border-block-end-width: 2px;
}

.aj-link:focus-visible {
  outline: 2px solid var(--color-on-dark);
  outline-offset: 4px;
}

/* -----------------------------------------------------------
   5 · The closing band (§9) — the one lit surface on the page
   ----------------------------------------------------------- */

/* E1.2: the band is the inverse of its page, so on a black page it is
   paper. The brightest moment is the moment the page asks for the project.

   The register is the site's, levelled at this build: 32px light, the form
   the 47 record pages, the three sector pages and the ledger already ship.
   Home's 700 uppercase was a board-7 leftover on one page out of the
   fifty-three built, and an uppercase imperative is the register E10 bars —
   home.css is amended to match rather than this page inheriting a second
   register for one component. */
.aj-band {
  padding-block: calc(var(--gap-section-major) / 2);
  background: var(--color-surface-dark);
}

.aj-band__line {
  margin: 0 0 var(--gap-block);
  max-inline-size: var(--measure-h2);
  font-size: var(--fs-h2);
  font-weight: var(--fw-light);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  color: var(--color-on-dark);
}

.aj-band__action {
  display: inline-block;
  padding-block: var(--gap-tight);
  padding-inline: var(--gap-heading);
  border: 1px solid var(--color-on-dark);
  font-size: var(--fs-metadata);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--color-on-dark);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.aj-band__action:hover,
.aj-band__action:focus-visible {
  background: var(--color-on-dark);
  color: var(--color-surface-dark);
}

/* -----------------------------------------------------------
   6 · Breakpoints — restack, never shrink
   ----------------------------------------------------------- */

@media (max-width: 1024px) {
  .aj-map {
    --mark-scale: 1.4;

    /* 400px svg on a 560 viewBox: 17 units renders at 12.1px. */
    --label-size: 1.0625rem;
  }

  .aj-map__svg {
    inline-size: 400px;
  }
}

/* §3.7 — below 821px the columns stack, map first at its own proportion,
   then the ledger. THE MAP IS NOT STICKY HERE: pinning it on a short
   viewport buys nothing and costs the reader a screen. */
@media (max-width: 820px) {
  .aj-standing__grid {
    display: block;
  }

  .aj-standing__map {
    position: static;
    margin-block-end: var(--gap-component);
  }

  .aj-map {
    --mark-scale: 1;

    /* Stacked, the svg is drawn 1:1, so a unit IS a pixel. */
    --label-size: 0.75rem;
  }

  .aj-map__svg {
    inline-size: 560px;
  }
}

@media (max-width: 639px) {
  .aj-map {
    --mark-scale: 1.75;
  }

  /* THE LABELS STOP HERE, AND THAT IS THE DECISION (3 Aug). At a 320px svg
     the 12px floor costs 21 user units; ten names that size on a 560-unit
     field collide with each other and with the marks they belong to. The
     ledger immediately below is the legend at this width — every district
     as real, selectable, announced text — so the map gives up the names
     rather than printing them too small to read or too big to place. */
  .aj-map__label {
    display: none;
  }

  .aj-map__svg {
    inline-size: 320px;
  }
}

/* The row's two parts stop competing for one line and stack, rather than
   the name being squeezed to fit its meta beside it. */
@media (max-width: 480px) {
  .aj-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }
}

/* -----------------------------------------------------------
   7 · Reduced motion
   ----------------------------------------------------------- */

/* tokens.css already clamps every transition to 0.01ms under reduce, so
   nothing needs zeroing here. What DOES need stating is the delay: a zero
   duration does not cancel a 34ms-per-mark stagger, and the map would sit
   blank for its whole sweep under the setting that exists to prevent
   exactly that. js/ajman.js does not arm at all under reduce; this is the
   belt to that brace.

   The ledger interaction is untouched: a fill change is not motion, and
   the reader who has asked for less of it still gets the map to answer. */
@media (prefers-reduced-motion: reduce) {
  .aj-map--armed .aj-mark,
  .aj-map--drawing .aj-mark {
    transform: scale(var(--mark-scale));
    transition-delay: 0s;
  }

  /* An armed coast is a MISSING COASTLINE, and clamping a duration does not
     un-hide it — the same argument as the armed label being a hidden name.
     So the dash is refused outright: no dasharray, nothing to offset. */
  .aj-map--armed .aj-coast,
  .aj-map--drawing .aj-coast {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    transition: none;
  }

  /* The armed label state IS a hidden name, and zeroing a duration does not
     un-arm anything — so the clip is refused outright rather than hurried.
     js/ajman.js does not arm under reduce at all; this is the second half,
     for an armed class that arrives any other way. RTL is restated because
     the rule it overrides is. */
  .aj-map--armed .aj-map__label,
  [dir="rtl"] .aj-map--armed .aj-map__label,
  .aj-map--drawing .aj-map__label {
    clip-path: inset(-12%);
    transition: none;
    transition-delay: 0s;
  }
}
