/* ════════════════════════════════════════════════════════
   regtimeline.css — THE ENFORCEMENT TIMELINE

   Extracted from landing.css so the graphic can appear on the
   jurisdiction pages too. Those pages load aipolicy.css, not
   landing.css, which is why the site's only real graphic sat on
   the homepage alone while the pages that are nothing but words
   had none.

   Markup: templates/website/_regulatory_timeline.html
   Geometry: website/timeline.py, from website/regulatory_dates.py
   ════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════
   THE ENFORCEMENT TIMELINE

   The site's first real graphic. Two rules shape it:

   1. It is built from text, not drawn as an SVG or a PNG, because an
      image of a date is invisible to ChatGPT and Google — and selling
      AI visibility from a page whose only graphic cannot be read by an
      AI is an argument against ourselves.
   2. Below 720px the positioned drawing is replaced by the list, which
      is in the document at every width. On a phone, percentage marks
      land on top of each other, and a horizontal scroller hides half
      the content behind a gesture most people never make.

   Contrast, measured on #0a1628: white 8.05:1 at 65%, amber 8.44:1,
   white 60% 7.06:1. The dimmest thing here is the year ticks at 55%,
   which is 6.1:1 — above AA for the small text they carry.
   ═══════════════════════════════════════════════════════════════ */
.reglane {
  background: #0a1628;
  padding: clamp(64px, 9vw, 104px) 24px;
  border-top: 1px solid rgba(255,255,255,0.08);
}

.reglane-inner { max-width: 1180px; margin: 0 auto; }

.reglane-header { max-width: 720px; margin-bottom: clamp(40px, 5vw, 64px); }

.reglane-title {
  font-size: clamp(1.75rem, 3.8vw, 2.75rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: #ffffff;
  text-wrap: balance;
  margin: 0 0 18px;
}

.reglane-sub {
  font-size: clamp(0.98rem, 1.3vw, 1.075rem);
  line-height: 1.65;
  color: rgba(255,255,255,0.65);
  max-width: 60ch;
  text-wrap: pretty;
  margin: 0;
}

/* ── The drawing ─────────────────────────────────────────────── */
/* The swap between the two versions is at the BOTTOM of this block, not
   here. `.reglane-list { display: grid }` is declared further down, and a
   media query placed above it loses to plain source order at equal
   specificity — which shipped both versions stacked on desktop until the
   render was measured. Same specificity means later wins; a media query
   is not a tiebreaker. */
.reglane-chart { display: none; }

/* The lane-name column, defined ONCE. Three rules need this measurement
   — the year axis, the lane name itself and the now-line's track — and
   when it was typed three times the third copy was wrong in a way no
   test could see: the now-line took its percentage of the FULL plot and
   then added the offset again, landing six months late. A number two
   rules must agree on is a number that belongs in one place. */
.reglane { --reglane-name-col: 148px; }

.reglane-years {
  position: relative;
  height: 22px;
  /* Matches .reglane-track's offset so a year tick sits above the marks
     it belongs to. Both read --reglane-name-col. */
  margin-left: var(--reglane-name-col);
}

.reglane-year {
  position: absolute;
  transform: translateX(-50%);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.55);
}

.reglane-plot { position: relative; }

/* Today's line runs the full height of the lanes, behind the marks. It
   is the one element that makes "already in force" a fact you can see
   rather than a colour you have to be told the meaning of. */
/* Inset to exactly where the marks start, so a percentage inside it
   means the same date it means on a lane. */
.reglane-nowtrack {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: var(--reglane-name-col);
  pointer-events: none;
}

.reglane-now {
  position: absolute;
  top: 0;
  bottom: 26px;
  width: 1px;
  background: repeating-linear-gradient(
    to bottom, rgba(245,158,11,0.55) 0 4px, transparent 4px 8px);
  z-index: 0;
}

.reglane-now-label {
  position: absolute;
  bottom: -22px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #f59e0b;
  white-space: nowrap;
}

.reglane-lane {
  display: flex;
  align-items: center;
  min-height: 74px;
  border-top: 1px solid rgba(255,255,255,0.1);
  position: relative;
  z-index: 1;
}
.reglane-lane:last-of-type { border-bottom: 1px solid rgba(255,255,255,0.1); }

.reglane-lane-name {
  width: var(--reglane-name-col);
  flex: 0 0 var(--reglane-name-col);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #ffffff;
  padding-right: 20px;
}

.reglane-track {
  position: relative;
  flex: 1;
  height: 74px;
  /* The hairline the marks sit on, drawn as a background layer so the
     element keeps both its pseudo-elements free. */
  background: linear-gradient(rgba(255,255,255,0.14), rgba(255,255,255,0.14))
              no-repeat left 28px / 100% 1px;
}

.reglane-mark {
  position: absolute;
  top: 28px;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.reglane-dot {
  width: 11px;
  height: 11px;
  flex: 0 0 11px;
  border: 2px solid #f59e0b;
  background: transparent;
}

.reglane-mark.is-live .reglane-dot,
.reglane-dot.is-live { background: #f59e0b; }

.reglane-mark-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: rgba(255,255,255,0.6);
  white-space: nowrap;
}

.reglane-mark.is-live .reglane-mark-label { color: #ffffff; }

/* The second shelf. Two obligations less than 9% of the axis apart print
   their labels on top of each other; timeline.py drops the later one to
   row 1 and this is where it lands. The dot stays on the line — only the
   label moves, or the reader loses the date's actual position. */
.reglane-mark.row-1 {
  flex-direction: column-reverse;
  top: 28px;
  transform: translate(-50%, calc(-50% + 34px));
}
.reglane-mark.row-1 .reglane-dot { transform: translateY(-34px); }

.reglane-key {
  display: flex;
  gap: 24px;
  /* Aligns the legend with the marks it explains. */
  margin: 28px 0 0 var(--reglane-name-col);
  font-size: 0.76rem;
  color: rgba(255,255,255,0.6);
}

.reglane-key-item { display: inline-flex; align-items: center; gap: 8px; }

/* ── The readable version ────────────────────────────────────── */
.reglane-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 32px;
}

.reglane-list-name {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #f59e0b;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.14);
}

.reglane-list ul { list-style: none; margin: 0; padding: 0; }

.reglane-list li {
  padding: 14px 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}

.reglane-list-date {
  font-size: 0.95rem;
  font-weight: 800;
  color: rgba(255,255,255,0.6);
  margin-right: 10px;
}
.reglane-list li.is-live .reglane-list-date { color: #ffffff; }

.reglane-list-state {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  border: 1px solid rgba(255,255,255,0.22);
  padding: 2px 7px;
}
.reglane-list li.is-live .reglane-list-state {
  color: #0a1628;
  background: #f59e0b;
  border-color: #f59e0b;
}

.reglane-list-detail {
  display: block;
  margin-top: 8px;
  font-size: 0.86rem;
  line-height: 1.55;
  color: rgba(255,255,255,0.6);
  text-wrap: pretty;
}

/* ── One version at a time ───────────────────────────────────── */
/* Placed last so it beats the base `display` on both elements. Above
   720px the drawing shows and the list is hidden; below it, the reverse.
   The list is always IN the document either way — it is what a screen
   reader and every AI crawler read, at every width. */
@media (min-width: 720px) {
  .reglane-chart { display: block; }
  .reglane-list  { display: none; }
}

@media (max-width: 600px) {
  .reglane { padding: 56px 16px; }
}


/* ── The reader's own lane ────────────────────────────────────────
   Set by `highlight` on the include, for the jurisdiction pages. The
   other three lanes stay fully legible: the point of showing them is
   the cross-border argument ("I'm a UK company" is not a defence), so
   this lifts one line rather than dimming the rest. Dimming would
   quietly undo the argument the page just made.

   A left border would be the reflex here and is wrong — a thick
   coloured side-stripe is the tell of a template callout. The lift is
   carried by a background wash and the weight of the lane name.
   ──────────────────────────────────────────────────────────────── */
.reglane-lane.is-focus {
  background: rgba(245, 158, 11, 0.07);
}

.reglane-lane.is-focus .reglane-lane-name {
  color: #f59e0b;
}

/* On a phone the drawing is replaced by the list, so the focus state
   has to exist there too or the emphasis vanishes at the width where
   most people read it. */
.reglane-list-lane.is-focus {
  background: rgba(245, 158, 11, 0.07);
  padding: 16px 18px;
  margin-left: -18px;
  margin-right: -18px;
}

/* "this page" — tells the reader which line is theirs without a key.
   Not uppercase-tracked like the lane name above it; it is a label on
   the label, and matching its treatment would read as a second title. */
.reglane-yours {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 7px;
  background: #f59e0b;
  color: #0a1628;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: none;
  vertical-align: middle;
}
