/* =============================================================== lc-surf.css ==
   /surfing/ — an honest instrument on a magazine.

   THE DIRECTION. This is Operate, not Persuade. Somebody opens it at 6.10am with
   one hand, deciding whether to put a board in a car, and on this coast the
   answer is no about 350 days a year. The design problem is therefore not "make
   surf look exciting" — it is to make the commonest state, flat, read as a
   finished page worth returning to rather than as a broken feature.

   The move that makes that possible: the page is about SECONDS, not feet. Every
   other surf feed leads with a height, and a height here is close to meaningless
   — 89% of all hours carry a swell period under eight seconds, so "2.6 ft" is
   almost always chop. So period leads typographically everywhere: it takes the
   display serif at the size the kite page gives knots, and the height is set
   beside it as the supporting figure.

   WHY THE SECTIONS DO NOT LOOK ALIKE. The verdict is a dark full-bleed band
   ending in a drawn cross-section of the actual water, because it is the only
   thing that must work at arm's length. The share ruler is a single rule, because
   it is one whole cut where the reader assumed it was not. The board is ruled
   rows, because it is a comparison. The forecast is a chart. The year is a chart
   of constants. The cams are photographs. The guide is editorial. A card would
   have flattened all seven into the same object.

   Tokens are the theme's own. --gd-* belongs to lc-guide.css, which is not
   enqueued on this slug, so every variable is read through its literal fallback
   and this file stands up alone. The condition greens and reds are lc-kite.css's,
   unchanged, because a rider and a surfer looking at the two pages on the same
   morning should not have to learn two colour systems.

   COLOUR WAS COMPUTED, NOT CHOSEN.

   Two jobs, two treatments. Condition is CATEGORICAL and inherits the kite page's
   validated pair — one green, one red, plus grey — where the sub-states are
   carried on texture rather than on extra hues, because the obvious
   green/amber/orange/red set failed CVD separation there and would fail it here.

   Period band is SEQUENTIAL: five ordered steps, so it is one ramp, light to
   dark, and the criterion is lightness monotonicity rather than adjacent-pair
   separation. Measured in OKLab, the paper ramp runs L = .873 / .774 / .675 /
   .556 / .428 and the dark-surface ramp .430 / .545 / .625 / .756 / .864 — both
   monotonic with near-even steps. The two lightest paper steps sit under 3:1
   against paper, which is allowed only with relief: every place the ramp appears
   carries a visible label, a legend, a tooltip and a table view, and none of them
   is the sole carrier of a fact.

   Every mark that carries a state also carries its word. Nothing on this page is
   encoded in colour alone.
   ========================================================================== */

#lc-surf {
  --s-ink:    var(--gd-ink,    #2d2e33);
  --s-muted:  var(--gd-muted,  #6c6d74);
  --s-line:   var(--gd-line,   #e5e5e7);
  --s-accent: var(--gd-accent, #e44e56);
  --s-well:   var(--gd-well,   #14161a);   /* never #000 */
  --s-paper:  var(--gd-paper,  #f7f6f4);
  --s-ease:   var(--gd-ease,   cubic-bezier(.22,.72,0,1));
  --s-serif:  'Playfair Display', 'PT Serif', Georgia, serif;
  --s-sans:   'Montserrat', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  /* Condition. lc-kite.css's validated pair, unchanged. */
  --s-go:     #00795a;
  --s-no:     #c02f37;
  --s-quiet:  #8a8b92;
  --s-go-d:   #1f9b73;
  --s-no-d:   #e35862;

  /* The far register's two weights, written out so the chart and the key that
     explains it are the same values rather than two guesses at the same idea.
     No new hues: solid is the pair at the weight "worth a look" already carries,
     reach is the same pair laid on lightly. */
  --s-go-s:    rgba(0, 121, 90, .70);
  --s-go-r:    rgba(0, 121, 90, .26);
  --s-no-s:    rgba(192, 47, 55, .85);
  --s-no-r:    rgba(192, 47, 55, .26);
  --s-quiet-s: rgba(138, 139, 146, .58);
  --s-quiet-r: rgba(138, 139, 146, .22);

  /* Period band, sequential. Paper first, then the well. The light end is a
     visible grey rather than a near-white one: the ribbon on the forecast is
     mostly this step on most days, and a step that disappears into the paper
     turns the page's central mark into what looks like a rendering fault. */
  --s-b1: #bfc1c6;  --s-b2: #9cb1a8;  --s-b3: #5da88d;  --s-b4: #2d8567;  --s-b5: #005e46;
  --s-d1: #4c5057;  --s-d2: #527a6c;  --s-d3: #2f9d78;  --s-d4: #63c6a2;  --s-d5: #a5e2c8;

  /* A hairline is right between rules but falls under 3:1 as the sole boundary
     of a control group, so a frame is the ink at low alpha rather than a sixth
     grey invented for the job. */
  --s-frame: rgba(45, 46, 51, .17);

  color: var(--s-ink);
}

/* There is no global border-box reset on this theme: `div` inherits one but `a`,
   `p` and `body` do not, so anything here that combines a width with padding or
   a border states its own box or renders wider than it asks for. */
#lc-surf .lcs-wrap,
#lc-surf .lcs-input,
#lc-surf .lcs-chip,
#lc-surf .lcs-secpick,
#lc-surf .lcs-row,
#lc-surf .lcs-next__go,
#lc-surf .lcs-alert__go,
#lc-surf .lcs-scale__bar,
#lc-surf .lcs-scale__seg { box-sizing: border-box; }

/* Only the 500 face of Montserrat is served on this site. Anything heavier here
   would be a synthesised bold, so small labels earn emphasis from caps and
   tracking instead of weight. */
#lc-surf .lcs-label,
#lc-surf .lcs-kicker {
  font: 500 11px/1.5 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-muted);
}

#lc-surf :focus-visible { outline: 2px solid var(--s-accent); outline-offset: 3px; }

/* ============================================================ the bleed rule ==
   The builder layout wraps this element in the theme's own `.uk-container`,
   which is content-box, 1200px, with 40px gutters. The dark bands have to reach
   the window edge and cannot do that from inside it, so the ancestor container is
   unwound once, here, and every band restates the site measure with a `.lcs-wrap`
   of its own.

   Done this way rather than with `width:100vw`, which on this site extends past
   the scrollbar, creates horizontal overflow and loops the sticky header.

   The explicit box-sizing is load-bearing: the theme's `.uk-container` ties a `*`
   reset on specificity and loads later, so without it this rule silently falls
   back to content-box and adds 40px of gutter back onto a 100% width. */
.uk-container:has(#lc-surf) {
  box-sizing: border-box;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}
.uk-section:has(#lc-surf) { padding-top: 0; padding-bottom: 0; }

/* The measure, restated by each band rather than borrowed from `.uk-container` —
   the reset above is written with :has(), so an inner `.uk-container` would match
   it too and every band would lose its gutters. 1280 minus the 40px gutters is
   the theme's own 1200px measure, so the page lines up with every other page on
   the site without depending on a class this file also writes rules about. */
#lc-surf .lcs-wrap {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 40px;
}
@media (max-width: 959px) { #lc-surf .lcs-wrap { padding: 0 20px; } }
@media (max-width: 639px) { #lc-surf .lcs-wrap { padding: 0 15px; } }

/* Visually hidden, still read aloud. */
#lc-surf .lcs-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* A synthetic reading has to announce itself. A screenshot of a fake swell that
   is not marked as one is a lie waiting to be repeated. */
.lcs-preview {
  margin: 0;
  /* Full-bleed band, but its sentence starts on the same left edge as the
     masthead below it. Flush to the window while every other line on the page
     starts at the measure reads as a strip that arrived from somewhere else. */
  padding: 11px max(40px, calc((100% - 1200px) / 2));
  background: var(--s-accent);
  color: #fff;
  font: 500 11px/1.5 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
}

/* ================================================================ the verdict ==
   The half-second read. What the ocean is doing, whether it is worth going, when
   the next window is, and what the height is actually made of — over a drawn
   cross-section of the real water, which is where "period, not height" stops
   being a claim and becomes something a reader can see. */
.lcs-mastband {
  position: relative;
  background: var(--s-well);
  color: #fff;
  padding: 0;
}
.lcs-mastband::after {
  /* Texture. A flat dark rectangle is the one thing that always reads as a CSS
     block rather than a printed panel; the grain does the job a press screen
     does, and it runs over the water too. */
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: .5;
  background-image: radial-gradient(rgba(255,255,255,.06) 1px, transparent 1px);
  background-size: 3px 3px;
}
.lcs-mast {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 26px 0 0;
  font: 500 11px/1 var(--s-sans);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: rgba(255,255,255,.6);
}
.lcs-mast__tick {
  display: inline-block;
  width: 30px;
  height: 3px;
  margin-right: 12px;
  vertical-align: 2px;
  background: var(--s-accent);
}
#lcs-stamp { color: rgba(255,255,255,.42); }
#lcs-stamp::before { content: '·'; margin: 0 .6em; }

/* What the page is, before what it says today. Set under the masthead rule and
   held to the copy column so the verdict headline still starts high. */
.lcs-lede {
  position: relative;
  z-index: 1;
  margin: 18px 0 0;
  max-width: 66ch;
  font-size: 15.5px;
  line-height: 1.66;
  color: rgba(255,255,255,.6);
}

.lcs-verdict {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  /* The verdict starts where the lede ends; only the mix bottoms out, so the two
     columns share a baseline without the headline being pushed down the page to
     meet a readout that happens to be tall today. */
  align-items: start;
  gap: 26px 56px;
  padding: 30px 0 12px;
}
.lcs-verdict .lcs-mix { align-self: end; }
.lcs-verdict__line {
  margin: 0;
  font-family: var(--s-serif);
  font-size: clamp(42px, 6vw, 84px);
  font-weight: 400;
  line-height: .98;
  letter-spacing: -.025em;
  color: #fff;
  text-wrap: balance;
}
/* The verdict word is the thing being read, so the state tints the headline
   itself rather than adding a pill beside it. Never colour alone — the sentence
   underneath says it too. */
.lcs-verdict[data-tone="go"]     .lcs-verdict__line { color: var(--s-go-d); }
.lcs-verdict[data-tone="danger"] .lcs-verdict__line { color: var(--s-no-d); }
.lcs-verdict__why {
  margin: 18px 0 0;
  max-width: 44ch;
  font-size: 17px;
  line-height: 1.6;
  color: rgba(255,255,255,.74);
}
/* ---------------------------------------------------------- the hazard axis ==
   A SECOND axis, independent of state, and the design has to keep it that way.

   The state machine ranks whether the water is worth riding. This answers
   whether it can hurt you, and the two are not the same question: seven feet of
   five-second chop under twenty knots of onshore wind is correctly called
   windswell — there is no wave in it — and is also the most dangerous water this
   coast produces. So this is not nested inside the state's own styling; it is a
   sibling that can appear over any verdict, including "Flat."

   It is NOT a warning bar and must never become one. This is an invitation-shaped
   page, and a permanent strip would be scrolled past within a week. It is rare by
   construction — a few afternoons a year — and it earns its loudness from that
   rarity, so it costs the layout nothing when it is absent: no reserved slot, no
   "no hazards today" reassurance.

   The 135-degree hatch is what makes it unmistakable, and on this page that
   texture means exactly one thing: this water is dangerous right now. The
   permanent per-spot hazards in the guide carry a solid rule instead, precisely
   so this one keeps its meaning. */
.lcs-verdict__hazard {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 4px 16px;
  margin: 20px 0 0;
  padding: 16px 0 0;
  max-width: 60ch;
  font-size: 14.5px;
  line-height: 1.58;
  color: #fff;
  background-image: repeating-linear-gradient(135deg, var(--s-no-d) 0 3px, transparent 3px 6px);
  background-size: 100% 5px;
  background-repeat: no-repeat;
}
.lcs-verdict__hazardl {
  font: 500 10px/1.6 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-no-d);
  white-space: nowrap;
}

/* --------------------------------------------------------- the next window ==
   Present in every state, not only the calm one. On a swell it says when this
   ends; on a flat day it is the entire reason to open the page — and on this
   coast most days are flat, so it is a fixed part of the band. */
.lcs-next {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  column-gap: 22px;
  row-gap: 2px;
  margin: 28px 0 0;
  padding: 18px 0 0;
  max-width: 760px;
  border-top: 1px solid rgba(255,255,255,.18);
}
.lcs-next__l {
  grid-row: 1 / span 2;
  align-self: center;
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-accent);
}
.lcs-next__v {
  grid-column: 2;
  margin: 0;
  font-family: var(--s-serif);
  font-size: 22px;
  line-height: 1.2;
  color: #fff;
}
.lcs-next__m {
  grid-column: 2;
  margin: 0;
  max-width: 46ch;
  font-size: 13.5px;
  line-height: 1.5;
  color: rgba(255,255,255,.62);
}
.lcs-next__go {
  grid-column: 3;
  grid-row: 1 / span 2;
  align-self: center;
  flex: none;
  padding: 11px 20px;
  border: 1px solid rgba(255,255,255,.34);
  border-radius: 0;
  background: transparent;
  color: #fff;
  font: 500 10px/1 var(--s-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.lcs-next__go:hover { background: #fff; border-color: #fff; color: var(--s-ink); }

/* ------------------------------------------------------------ what is forming ==
   The one line on this page that is about a swell nobody can see yet.

   It borrows its mark rather than inventing one. Past the seam the forecast draws
   windows as OUTLINED chips where the near ones are filled — the page's existing
   grammar for "the model sees it, and it does not see the hour". This is that
   chip promoted to the band, at the size a sentence needs: a hairline in the go
   colour, no fill, square. Anything with a background would have read as a card,
   and there are no cards on this page.

   It is rare by construction — a handful of mornings a year clear the three tests
   in lc-surf.js — so like the hazard it costs the layout nothing when it is
   absent. No reserved slot, no rule waiting for it, and no "nothing forming"
   reassurance, which the paragraph above it already carries on the days it is
   true.

   Placed last in the copy column on purpose. The verdict headline has to win the
   half second on its own, and this is set two steps under it in size and one in
   weight so the eye reaches it after the answer rather than instead of it. */
.lcs-forming {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 6px 18px;
  box-sizing: border-box;
  margin: 20px 0 0;
  padding: 15px 20px 16px;
  /* The measure of the next-window group above, so the frame closes on the same
     right edge as the button in it. Subordination is carried by size and colour,
     not by an arbitrary step in from a line it should be aligning to. */
  max-width: 760px;
  /* An inset shadow rather than a border: the box sits inside the measure the
     rule above it sets, and a border would push it a pixel wider on each side.
     Alpha is high because green composited onto a near-black ground loses most
     of its chroma — at .4 this hairline read as grey, which is the one thing it
     must not do. */
  box-shadow: inset 0 0 0 1px rgba(31, 155, 115, .58);
}
.lcs-forming__l {
  font: 500 10px/1.7 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-go-d);
  white-space: nowrap;
}
.lcs-forming__t {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.62;
  color: rgba(255,255,255,.78);
  text-wrap: pretty;
}
/* Tertiary, and it stays inside the sentence — the last clause of the line is
   where a reader has just decided they want to look, so the way to look is there
   rather than parked underneath as a second button. */
.lcs-forming__go {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--s-go-d);
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: inset 0 -1px 0 rgba(31, 155, 115, .45);
  transition: box-shadow .2s var(--s-ease), color .2s var(--s-ease);
}
.lcs-forming__go::after { content: ' \2192'; }
.lcs-forming__go:hover { color: #fff; box-shadow: inset 0 -1px 0 #fff; }
.lcs-forming__go:active { box-shadow: inset 0 -2px 0 #fff; }

/* ------------------------------------------------------------- the mix ==
   The decomposition, and the reason the page exists: the number every other feed
   prints is the total, and one of the two things adding up to it is not a wave.
   Set as a small ruled instrument rather than a stat tile — the bars share one
   scale so the split is a length, not two percentages to compare. */
.lcs-mix {
  position: relative;
  z-index: 1;
  padding: 18px 0 0;
  border-top: 1px solid rgba(255,255,255,.18);
}
.lcs-mix__h {
  margin: 0 0 14px;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
}
.lcs-mix__r {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: baseline;
  gap: 4px 16px;
  padding: 11px 0 12px;
  border-top: 1px solid rgba(255,255,255,.1);
}
.lcs-mix__r:first-of-type { border-top: 0; }
.lcs-mix__n {
  font: 500 11px/1.5 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.74);
}
.lcs-mix__v, .lcs-mix__p { font-variant-numeric: tabular-nums; white-space: nowrap; }
.lcs-mix__v strong, .lcs-mix__p strong {
  font-family: var(--s-serif);
  font-weight: 400;
  font-size: 25px;
  line-height: 1;
  color: #fff;
}
.lcs-mix__p strong { font-size: 30px; }
.lcs-mix__v i, .lcs-mix__p i {
  margin-left: 3px;
  font: 500 10px/1 var(--s-sans);
  font-style: normal;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255,255,255,.46);
}
.lcs-mix__d {
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .1em;
  text-align: right;
  white-space: nowrap;
  color: rgba(255,255,255,.5);
}
.lcs-mix__bar { grid-column: 1 / -1; display: block; height: 4px; background: rgba(255,255,255,.1); }
.lcs-mix__fill { display: block; height: 100%; background: var(--s-d1); }
.lcs-mix__r[data-b="chop"] .lcs-mix__fill { background: var(--s-d1); }
.lcs-mix__r[data-b="wind"] .lcs-mix__fill { background: var(--s-d2); }
.lcs-mix__r[data-b="grnd"] .lcs-mix__fill { background: var(--s-d3); }
.lcs-mix__r[data-b="long"] .lcs-mix__fill { background: var(--s-d4); }
.lcs-mix__r[data-b="rare"] .lcs-mix__fill { background: var(--s-d5); }
/* The split, said in words under the two rows that draw it. Set at reading size
   rather than as a caption, because on most days it is the single sentence that
   does the page's whole job. */
.lcs-mix__c {
  margin: 16px 0 0;
  padding: 13px 0 0;
  border-top: 1px solid rgba(255,255,255,.14);
  font-size: 14px;
  line-height: 1.6;
  color: rgba(255,255,255,.84);
}
.lcs-mix__f {
  margin: 10px 0 0;
  font: 500 11.5px/1.6 var(--s-sans);
  color: rgba(255,255,255,.5);
}
.lcs-mix__q {
  margin: 8px 0 0;
  font: 500 10.5px/1.65 var(--s-sans);
  color: rgba(255,255,255,.34);
}

/* ================================================================= the sea ==
   The page's one drawn object, and the counterpart of the kite page's dial.

   Horizontal is true: 720 feet of open water, and a wave's spacing is
   5.12 * period^2 feet, so a six-second swell puts a crest every 184 ft and a
   nine-second one every 415. That is why the drawing works where a sentence does
   not — the reader is not told the difference, they see fifteen bumps where two
   lines should be. Vertical is exaggerated, and the caption says by how much,
   because two feet drawn true across 720 would be a twentieth of a pixel. */
.lcs-sea {
  position: relative;
  z-index: 1;
  margin: 0;
  line-height: 0;
}
.lcs-sea__svg { display: block; width: 100%; height: auto; }
.lcs-sea__fill { fill: rgba(255,255,255,.075); }
.lcs-sea__line { fill: none; stroke: rgba(255,255,255,.62); stroke-width: 1.5; }
/* The gate, drawn behind and dashed: green because it is the thing worth having,
   dashed because it is not what is out there. */
.lcs-sea__ghost { fill: none; stroke: var(--s-go-d); stroke-width: 1.4; stroke-dasharray: 5 5; opacity: .78; }
.lcs-sea__dimline { fill: none; stroke: rgba(255,255,255,.4); stroke-width: 1; }
.lcs-sea__dimt {
  fill: rgba(255,255,255,.6);
  font: 500 10px var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.lcs-sea__dim--ghost .lcs-sea__dimline { stroke: var(--s-go-d); opacity: .7; }
.lcs-sea__dim--ghost .lcs-sea__dimt { fill: var(--s-go-d); }
.lcs-sea__cap {
  padding: 0 40px 20px;
  max-width: 1280px;
  margin: 0 auto;
  font: 500 10px/1.7 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.36);
}

/* ==================================================== the department rule ==
   Same object lc-guide.css sets on the guide fronts and lc-kite.css repeats: a
   hairline with the accent tick on it, the name in the display serif, the note as
   a small label on the same baseline. Repeated so the page reads as part of the
   site rather than as a widget dropped into it. */
.lcs-head {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 28px;
  margin: 0 0 22px;
  padding-top: 16px;
  border-top: 1px solid var(--s-line);
}
.lcs-head::before {
  content: '';
  position: absolute;
  top: -1px;
  left: 0;
  width: 46px;
  height: 3px;
  background: var(--s-accent);
}
.lcs-head__t {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-family: var(--s-serif);
  font-size: 27px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--s-ink);
}
.lcs-head__m {
  flex: 0 1 auto;
  max-width: 42%;
  text-align: right;
  font: 500 11px/1.55 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
  text-wrap: balance;
}
.lcs-sec { margin: 0 0 64px; }
.lcs-sec--first { padding-top: 54px; }
.lcs-group {
  margin: 44px 0 4px;
  font: 500 11px/1.5 var(--s-sans);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-standfirst {
  margin: 0 0 20px;
  max-width: 64ch;
  font-size: 16.5px;
  line-height: 1.68;
  color: var(--s-ink);
}
.lcs-note { margin: 0; font: 500 12px/1.7 var(--s-sans); color: var(--s-muted); }
.lcs-note--tight { margin-top: 14px; max-width: 74ch; }
.lcs-mast--sec { padding-bottom: 22px; }
/* The bottom margin is padding on purpose: as a margin it collapses straight
   out through the band's own bottom edge and leaves a strip of white page
   between two dark sections. */
.lcs-camnote {
  margin: 16px 0 0;
  padding-bottom: 34px;
  max-width: 64ch;
  font: 500 11.5px/1.65 var(--s-sans);
  color: rgba(255,255,255,.5);
}

/* ============================================================ the share rule ==
   One whole, cut where the reader assumed it was not. A stacked bar is an unusual
   thing to reach for and it is the right mark here, because the encoding is not a
   comparison between five categories — it is the proportion, and the proportion
   IS the argument: the two useless bands take 89% of the rule.

   The three bands worth driving for total 11.2%, too narrow to label at any page
   width. Rather than lie about the widths, that tail is opened up underneath as a
   magnified detail, the way a map inset works. */
.lcs-scale { margin: 52px 0 0; }
.lcs-scale__barwrap { position: relative; }
/* The separator between two adjacent fills is the page surface, not a sixth
   grey: a 1px line in --s-line between #bfc1c6 and #9cb1a8 is under 1.1:1 and
   the two bands read as one smear at arm's length, which is the opposite of
   what a cut is for. */
.lcs-scale__bar {
  display: flex;
  width: 100%;
  height: 46px;
  border: 1px solid var(--s-frame);
  background: #fff;
  gap: 2px;
}
.lcs-scale__bar--det { height: 26px; }
.lcs-scale__seg { display: block; height: 100%; min-width: 1px; }
.lcs-scale__seg[data-b="chop"] { background: var(--s-b1); }
.lcs-scale__seg[data-b="wind"] { background: var(--s-b2); }
.lcs-scale__seg[data-b="grnd"] { background: var(--s-b3); }
.lcs-scale__seg[data-b="long"] { background: var(--s-b4); }
.lcs-scale__seg[data-b="rare"] { background: var(--s-b5); }

/* You are here. The ruler is complete without it — it is a measured constant, so
   it is server-rendered — and the reading only says where today lands on it. */
/* Above the rule, not below it: under the bar the flag lands on the band labels
   and covers the thing it is pointing into. */
.lcs-scale__now { position: absolute; top: -1px; bottom: -1px; z-index: 2; }
.lcs-scale__nowline {
  position: absolute;
  top: -8px;
  bottom: -1px;
  left: -1px;
  width: 2px;
  background: var(--s-accent);
}
.lcs-scale__nowlab {
  position: absolute;
  top: -32px;
  left: -1px;
  padding: 4px 9px;
  background: var(--s-accent);
  color: #fff;
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
}
.lcs-scale__now[data-flip="true"] .lcs-scale__nowlab { left: auto; right: -1px; }

.lcs-scale__labs { display: flex; margin: 10px 0 0; gap: 1px; }
/* Equal thirds. The narrowest detail band is 0.2% of all hours, and a label sized
   to its own segment wraps one letter to a line. */
.lcs-scale__labs--det { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.lcs-scale__dl::before {
  content: '';
  display: block;
  width: 22px;
  height: 4px;
  margin: 0 0 8px;
}
.lcs-scale__dl[data-b="grnd"]::before { background: var(--s-b3); }
.lcs-scale__dl[data-b="long"]::before { background: var(--s-b4); }
.lcs-scale__dl[data-b="rare"]::before { background: var(--s-b5); }
.lcs-scale__l, .lcs-scale__dl {
  display: block;
  min-width: 0;
  padding-right: 12px;
  border-top: 1px solid var(--s-line);
  padding-top: 8px;
  font: 500 10.5px/1.6 var(--s-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-scale__l strong, .lcs-scale__dl strong {
  display: block;
  font-family: var(--s-serif);
  font-size: 17px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--s-ink);
}
.lcs-scale__l em, .lcs-scale__dl em {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-variant-numeric: tabular-nums;
  color: var(--s-ink);
}
.lcs-scale__l--tail { color: var(--s-go); }
.lcs-scale__l--tail em { color: var(--s-go); }

.lcs-scale__detail { margin: 34px 0 0; padding: 0 0 0 0; }
.lcs-scale__dh {
  margin: 0 0 9px;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-scale__dh::before {
  content: '';
  display: inline-block;
  width: 22px;
  height: 1px;
  margin-right: 10px;
  vertical-align: 3px;
  background: var(--s-muted);
}

/* =========================================================== the spot rows ==
   Seven beaches as a comparison, so they are a ruled instrument rather than seven
   boxes: one grid, 1px gaps, the container colour showing through as the rules.
   Nothing inside draws a border. */
.lcs-rows {
  display: grid;
  gap: 1px;
  border: 1px solid var(--s-frame);
  background: var(--s-line);
}
.lcs-row {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr) 76px 74px 58px 76px 74px 104px;
  align-items: center;
  gap: 0 16px;
  width: 100%;
  margin: 0;
  padding: 13px 18px;
  border: 0;
  border-radius: 0;
  background: #fff;
  text-align: left;
  cursor: pointer;
  transition: background .18s var(--s-ease);
}
.lcs-row:hover { background: var(--s-paper); }
.lcs-row[aria-pressed="true"] { background: var(--s-paper); box-shadow: inset 3px 0 0 var(--s-accent); }
.lcs-row:focus-visible { outline: 2px solid var(--s-accent); outline-offset: -4px; }

/* ------------------------------------------------------------- the meter ==
   The row's mark. It replaced a miniature of the hero cross-section, which kept
   that drawing's geometry and lost everything that made the geometry legible: at
   a hundred pixels an honest four-second sea is fourteen crests, and fourteen
   crests in a 26px box is a saw-tooth. A form that needs a scale bar and a
   caption is the wrong form at this size.

   What replaced it measures instead of illustrating. One scale for all seven
   beaches, zero to twelve seconds, with a rule at eight — the threshold the
   ruler two sections above has already named and costed. The rule is a
   percentage of the track, so it lands at the same x in every row and the column
   resolves into a single vertical line down the board: the reader can see which
   beaches reach it without reading one figure.

   The fill is the period band's own step from this page's sequential ramp, whose
   key is already printed directly under this board. No new encoding, and the
   board and the ruler become one instrument rather than two pictures of the same
   variable. */
.lcs-row__m { display: block; }
/* The track is lighter than the wind bar's, and for the opposite reason. That
   one is filled with a mid grey, so its empty end has to be dark enough to look
   measured. This one is filled with the ramp's lightest step on nine mornings in
   ten — and #bfc1c6 on an 11% track is barely over 1.3:1, which is how a whole
   column of live readings comes to look like marks that failed to draw. So the
   track drops back and a hairline underneath carries the full extent instead:
   the measure is framed by a rule rather than by its own emptiness. */
.lcs-meter {
  position: relative;
  display: block;
  width: 112px;
  height: 8px;
  background: rgba(45,46,51,.055);
}
.lcs-meter::before {
  content: '';
  position: absolute;
  right: 0;
  bottom: -4px;
  left: 0;
  height: 1px;
  background: var(--s-frame);
}
.lcs-meter__bar { display: block; height: 100%; background: var(--s-b1); }
.lcs-meter__bar[data-b="chop"] { background: var(--s-b1); }
.lcs-meter__bar[data-b="wind"] { background: var(--s-b2); }
.lcs-meter__bar[data-b="grnd"] { background: var(--s-b3); }
.lcs-meter__bar[data-b="long"] { background: var(--s-b4); }
.lcs-meter__bar[data-b="rare"] { background: var(--s-b5); }
/* The gate. It stands proud of the track top and bottom and crosses the baseline
   below it, so it reads as a rule laid ACROSS the measure rather than as a
   segment boundary inside it — the difference between "this bar is in two parts"
   and "this bar has not got there". Full ink, because it is the only mark on the
   board that is a threshold rather than a reading, and a threshold drawn at the
   weight of a hairline gets read as a tick.

   Painted over the bar rather than under it. A bar that hid the rule would take
   the reference away from the one row where it has finally been beaten, and on a
   day when all seven cross it would take the rule off the board entirely. Over
   the top, a bar past the gate reads the way a finish line does. */
.lcs-meter::after {
  content: '';
  position: absolute;
  top: -5px;
  bottom: -6px;
  left: 66.667%;
  width: 1px;
  background: var(--s-ink);
}
.lcs-meter--big { width: 132px; height: 10px; }

.lcs-row__name { display: grid; min-width: 0; }
.lcs-row__name strong {
  font-family: var(--s-serif);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--s-ink);
}
.lcs-row__detail {
  font: 500 10.5px/1.5 var(--s-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s-muted);
}
/* Period takes the display size every other surf report gives the height. That
   inversion is the page's whole argument, stated in type. */
.lcs-row__p { justify-self: end; white-space: nowrap; font-variant-numeric: tabular-nums; }
.lcs-row__p strong {
  font-family: var(--s-serif);
  font-weight: 400;
  font-size: 32px;
  line-height: 1;
  color: var(--s-ink);
}
.lcs-row__p i {
  margin-left: 2px;
  font: 500 11px/1 var(--s-sans);
  font-style: normal;
  letter-spacing: .1em;
  color: var(--s-muted);
}
.lcs-row[data-st="firing"] .lcs-row__p strong { color: var(--s-go); }
.lcs-row[data-st="big"]    .lcs-row__p strong { color: var(--s-no); }

.lcs-row__ft { display: grid; font-variant-numeric: tabular-nums; }
.lcs-row__ft strong {
  font: 500 14px/1.3 var(--s-sans);
  letter-spacing: .04em;
  color: var(--s-ink);
}
.lcs-row__ft span {
  font: 500 9.5px/1.4 var(--s-sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-row__dir { display: grid; }
.lcs-row__dir strong { font: 500 13px/1.3 var(--s-sans); letter-spacing: .08em; color: var(--s-ink); }
.lcs-row__dir span {
  font: 500 10px/1.3 var(--s-sans);
  font-variant-numeric: tabular-nums;
  color: var(--s-muted);
}
.lcs-row__wind { display: grid; }
.lcs-row__wind strong {
  font: 500 13px/1.3 var(--s-sans);
  font-variant-numeric: tabular-nums;
  color: var(--s-ink);
}
.lcs-row__wind span {
  font: 500 10px/1.3 var(--s-sans);
  letter-spacing: .1em;
  color: var(--s-muted);
}

/* Wind on the face, as a bar. "0.72" is not readable; two thirds of a bar next to
   a quarter of a bar is. Full means offshore or glassy. */
/* The empty end of this bar has to look measured rather than unpainted: on an
   onshore morning every one of the seven fills is a stub, and a track at
   --s-line is 1.15:1 on white, so the row reads as seven marks that failed to
   draw. The track is a shade the eye registers as the rest of the measure. */
.lcs-row__q { display: block; height: 6px; background: rgba(45,46,51,.11); }
.lcs-row__qfill { display: block; min-width: 3px; height: 100%; background: var(--s-quiet); transition: width .3s var(--s-ease); }
.lcs-row[data-st="firing"] .lcs-row__qfill { background: var(--s-go); }
.lcs-row[data-st="worth"]  .lcs-row__qfill { background: var(--s-go); opacity: .55; }
.lcs-row[data-st="blown"]  .lcs-row__qfill { background: var(--s-no); }
.lcs-row[data-st="big"]    .lcs-row__qfill { background: var(--s-no); }

.lcs-row__word {
  justify-self: end;
  padding: 4px 0 4px 12px;
  border-left: 3px solid var(--s-quiet);
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--s-muted);
  white-space: nowrap;
}
.lcs-row[data-st="firing"] .lcs-row__word { border-color: var(--s-go); color: var(--s-go); }
.lcs-row[data-st="worth"]  .lcs-row__word { border-color: var(--s-go); }
.lcs-row[data-st="big"]    .lcs-row__word { border-color: var(--s-no); color: var(--s-no); }
.lcs-row[data-st="blown"]  .lcs-row__word { border-color: var(--s-no); }

/* The second axis on the board. It sits UNDER the state word rather than
   replacing it, because the row has to be able to say "Windswell" and "Hazard"
   at once — that combination is the whole reason the two are separate. */
.lcs-row__hz {
  display: block;
  margin-top: 3px;
  font: 500 9.5px/1.4 var(--s-sans);
  font-style: normal;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--s-no);
}
.lcs-row[data-hz="true"] .lcs-row__word { border-color: var(--s-no); }

/* ------------------------------------------------------------- the axis ==
   The scale, stated once. A mark nobody can decode is decoration; a number
   printed on all seven marks is chaos and goes unread. One line under the board
   is the space between those two failures — and it sits INSIDE the frame,
   because an axis belongs to its instrument and not to the page around it.

   It reuses the row's own first two columns, so the ticks fall on the track they
   describe rather than near it. */
/* Top-aligned, not centred. Centred against a two-line sentence the tick's stem
   points into the middle of a paragraph; from the top it points straight up the
   column at the last rule on the board, which is what makes the strip read as
   that instrument's axis rather than as a note parked beside it. */
.lcs-rowaxis {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  align-items: start;
  gap: 0 16px;
  padding: 9px 18px 13px;
  background: var(--s-paper);
}
.lcs-rowaxis__m { position: relative; display: block; height: 14px; }
/* The gate's label, on the gate's own x and tied to it by a stem, so it names
   the rule rather than sitting near it. Set in the ink the rule is drawn in:
   it is the one number under this board that is a threshold and not a reading. */
.lcs-rowaxis__g {
  position: absolute;
  top: 6px;
  left: 66.667%;
  transform: translateX(-50%);
  font: 500 9.5px/1 var(--s-sans);
  font-style: normal;
  font-variant-numeric: tabular-nums;
  letter-spacing: .08em;
  color: var(--s-ink);
  white-space: nowrap;
}
.lcs-rowaxis__g::before {
  content: '';
  position: absolute;
  top: -6px;
  left: 50%;
  width: 1px;
  height: 4px;
  background: var(--s-ink);
}
.lcs-rowaxis__t {
  margin: 0;
  max-width: 68ch;
  font: 400 12px/1.6 var(--s-sans);
  color: var(--s-muted);
}

/* --------------------------------------------------------------- legends ==
   Always present. Two hues carry seven states, so the words are what actually
   separate them and the swatches only speed the lookup up. */
.lcs-legend { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 18px 0 0; }
.lcs-legend span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 500 10.5px/1.5 var(--s-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-legend i { width: 14px; height: 14px; border: 0; }
.lcs-sw-on     { background: var(--s-go); }
.lcs-sw-worth  { background: repeating-linear-gradient(45deg, var(--s-go) 0 2px, transparent 2px 4px); }
.lcs-sw-wind   { background: var(--s-quiet); opacity: .55; }
.lcs-sw-blown  { background: var(--s-no); opacity: .38; }
.lcs-sw-shadow { background: repeating-linear-gradient(135deg, var(--s-quiet) 0 2px, transparent 2px 4px); }
.lcs-sw-big    { background: repeating-linear-gradient(135deg, var(--s-no) 0 2px, transparent 2px 4px); }
.lcs-sw-flat   { background: var(--s-line); box-shadow: inset 0 0 0 1px var(--s-frame); }
/* The floor, as it is actually drawn: a rule with the region it closes off
   underneath it. A bare line would no longer describe the mark on the chart. */
.lcs-sw-line   {
  background: linear-gradient(to bottom, transparent 0 6px, rgba(45,46,51,.14) 6px 100%);
  box-shadow: inset 0 7px 0 -6px var(--s-ink);
  opacity: .8;
}

/* The fold. Quiet by construction — it is a way back to the full key, not a
   control anybody needs to find, so it is set as the legend's own label with a
   rule under it rather than as a button pretending to be one. */
.lcs-legend__more {
  margin-left: 6px;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--s-line);
  background: none;
  font: 500 10.5px/1 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
  cursor: pointer;
  transition: color .2s var(--s-ease), border-color .2s var(--s-ease);
}
.lcs-legend__more:hover { color: var(--s-accent); border-color: var(--s-accent); }
/* The forecast's own swatches. They match the bars, which are fill-only. */
.lcs-sw-worth2   { background: var(--s-go); opacity: .5; }
.lcs-sw-bigsolid { background: var(--s-no); opacity: .9; }
/* The far mark, drawn as it is drawn: the height held all the way through with
   the reach laid on above it. Built from the same two tokens the chart uses, so
   the key cannot drift away from the thing it explains. */
.lcs-legend__far { gap: 8px; }
.lcs-sw-reach {
  background: linear-gradient(to bottom, var(--s-go-r) 0 45%, var(--s-go-s) 45% 100%);
}
.lcs-legend__ramp { gap: 4px; }
.lcs-legend__ramp i:first-of-type { margin-left: 6px; }
.lcs-legend__ramp i { width: 16px; height: 9px; }
.lcs-legend__ramp i[data-b="chop"] { background: var(--s-b1); }
.lcs-legend__ramp i[data-b="wind"] { background: var(--s-b2); }
.lcs-legend__ramp i[data-b="grnd"] { background: var(--s-b3); }
.lcs-legend__ramp i[data-b="long"] { background: var(--s-b4); }
.lcs-legend__ramp i[data-b="rare"] { background: var(--s-b5); margin-right: 6px; }
/* The gate on the ramp. The server-rendered key already puts "12 s" on the
   long/rare boundary, so eight seconds is named the same way at its own — and
   marked, because unlike twelve it is the line the whole page turns on. */
.lcs-legend__ramp i[data-b="grnd"] { box-shadow: inset 2px 0 0 var(--s-ink); }
.lcs-legend__gate { font-weight: 500; color: var(--s-ink); }

/* ============================================================== the forecast ==
   Small multiples on one time axis, and two marks stacked on it rather than two
   scales on one plot. The bars are swell HEIGHT with the two-foot floor drawn
   across them; the ribbon under each strip is the PERIOD band for the same hour.
   Stacking is the point: what a reader needs to see is that the tall bars and the
   dark ribbon cells do not line up, which is height-without-seconds made visible
   rather than argued. */
.lcs-forecast { display: grid; gap: 0; }
/* Two rows. The upper one names which register you are reading and the lower one
   names the day, because on this axis those are two different questions: an hour
   in the near register and a block in the far one are not the same kind of fact,
   and a reader who has not been told that will read a block as a promise. */
.lcs-axis {
  position: relative;
  height: 36px;
  margin: 0 0 2px;
  border-bottom: 1px solid var(--s-line);
}
.lcs-axis__reg {
  position: absolute;
  top: 0;
  box-sizing: border-box;
  padding-left: 7px;
  border-left: 1px solid var(--s-line);
  font: 500 9px/1.5 var(--s-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--s-muted);
  white-space: nowrap;
  overflow: hidden;
}
/* The seam. Its rule is the same ink as the fold drawn inside every strip below
   it, so the boundary reads as one line running the height of the section rather
   than as eight unrelated ticks. */
.lcs-axis__reg[data-reg="far"] { border-left-color: rgba(45, 46, 51, .32); }
.lcs-axis__d {
  position: absolute;
  bottom: 5px;
  padding-left: 7px;
  border-left: 1px solid var(--s-line);
  font: 500 10px/1 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
  white-space: nowrap;
}
/* A week of days is compressed into the right third, so the names there are set
   tighter — and the last one sits within a few per cent of the edge, where it
   would hang off. A dimension label in that position moves to the other side of
   its own tick rather than being cropped. */
.lcs-axis__d[data-far="true"] { letter-spacing: .08em; }
/* Set by the live layer only when two names are measured to be touching, so a
   font that loads wider than expected costs tracking rather than a whole day. */
.lcs-axis[data-tight="true"] .lcs-axis__d[data-far="true"] {
  letter-spacing: 0;
  padding-left: 3px;
}
.lcs-axis__d[data-flip="true"] {
  padding: 0 7px 0 0;
  border-left: 0;
  border-right: 1px solid var(--s-line);
  transform: translateX(-100%);
}
.lcs-strip { padding: 14px 0 15px; border-bottom: 1px solid var(--s-line); }
.lcs-strip[data-sel="true"] { background: var(--s-paper); }
.lcs-strip__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  margin: 0 0 8px;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}
.lcs-strip__n { font-family: var(--s-serif); font-size: 18px; color: var(--s-ink); }
.lcs-strip__s {
  font: 500 10px/1 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-strip[data-sel="true"] .lcs-strip__s { color: var(--s-accent); }
.lcs-strip__svg { display: block; width: 100%; height: 56px; }
.lcs-nowin {
  margin: 0 0 22px;
  max-width: 68ch;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--s-ink);
}

.lcs-strip__far   { fill: rgba(45,46,51,.026); pointer-events: none; }
.lcs-strip__night { fill: rgba(45,46,51,.055); }
.lcs-strip__day   { stroke: var(--s-line); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* Past the seam the day is the unit the marks are drawn in, so the ruling that
   bounds them carries more ink. The chart states its own resolution with the
   lines it draws — fine grain unruled on the left, ruled into days on the
   right — which is the confidence signal arriving as structure rather than as a
   fade. Nothing here is quietened; a quietened chart reads as broken data. */
.lcs-strip__day[data-far="true"] { stroke: var(--s-frame); }
.lcs-strip__fold {
  stroke: rgba(45, 46, 51, .32);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.lcs-strip__base  { stroke: var(--s-frame); stroke-width: 1; vector-effect: non-scaling-stroke; }

/* The gate, in two dimensions. See the block comment in lc-surf.js: ink is the
   threshold in both, colour stays reserved for what the hour actually is.

   The floor is a veil in the paper's own colour laid over the bars, so the two
   feet that carry no wave are quietened wherever they occur and what stands
   above the line keeps full weight. Paper rather than ink: the mark's job is to
   take something away, and adding grey to a grey bar reads as a second state. */
.lcs-strip__floor { fill: var(--s-paper); opacity: .42; pointer-events: none; }
.lcs-strip__gate {
  stroke: var(--s-ink);
  stroke-width: 1;
  opacity: .5;
  vector-effect: non-scaling-stroke;
}
/* Above the range, and it is not more of a good thing. The red says so; the rule
   is solid because it is a limit and not a projection. */
.lcs-strip__over { fill: var(--s-no); opacity: .07; }
.lcs-strip__ceil {
  stroke: var(--s-no);
  stroke-width: 1;
  opacity: .55;
  vector-effect: non-scaling-stroke;
}
.lcs-strip__bracket { fill: none; stroke: var(--s-go); stroke-width: 1.5; vector-effect: non-scaling-stroke; }

/* Fill only. See the note in lc-surf.js: a hatch on a seven-pixel bar inside a
   horizontally stretched chart catches one pattern line and reads as dirt. */
/* The ordering here is the state ladder, but the FLOOR of it is what decides
   whether this section is a chart or a smudge. Nine days in ten every bar on
   all seven strips is `flat`, and at .22 of #8a8b92 that is #e3e3e5 — under
   1.2:1 on paper. The page then answers its most-asked question with 168 marks
   nobody can see, which is the exact failure the ramp comment at the top of
   this file warns about, arriving on a different mark.

   The ladder is set higher than it reads, because the two-foot veil is laid over
   the bottom of every bar and takes roughly a third of it back. Quietening the
   fills as well would be doing the same job twice, and the second time to a mark
   that had nothing left to give — a chart of ghosts, which is what a flat week
   looked like while both were in force. The ladder itself is unchanged: firing
   still doubles shadowed. */
.lcs-strip__bar { fill: var(--s-quiet); opacity: .64; transition: opacity .15s ease; }
.lcs-strip__bar:hover { opacity: 1; }
.lcs-strip__bar[data-st="firing"] { fill: var(--s-go); opacity: 1; }
.lcs-strip__bar[data-st="worth"]  { fill: var(--s-go); opacity: .7; }
.lcs-strip__bar[data-st="big"]    { fill: var(--s-no); opacity: .92; }
.lcs-strip__bar[data-st="blown"]  { fill: var(--s-no); opacity: .5; }
.lcs-strip__bar[data-st="windswell"] { fill: var(--s-quiet); opacity: .74; }
.lcs-strip__bar[data-st="shadowed"]  { fill: var(--s-quiet); opacity: .56; }
.lcs-strip__bar[data-st="flat"]      { fill: var(--s-quiet); opacity: .5; }
/* Hours already gone. Still legible — the shape of the morning is the context
   for the afternoon — but plainly behind the live part of the chart. */
.lcs-strip__bar[data-day="0"] { opacity: .32; }
.lcs-strip__bar[data-day="0"][data-st="firing"] { opacity: .48; }
.lcs-strip__bar[data-day="0"][data-st="big"] { opacity: .46; }

/* ------------------------------------------------- past the seam: hold and reach ==
   The far register's mark is deliberately NOT an hourly bar with less ink in it.
   Fading a bar reads as missing data; changing the mark reads as a different kind
   of statement, which is what it is. The solid part is the height the block holds
   the whole way through and the faint part above is the most it reaches, so the
   eye can run along the tops for the shape of a swell filling and along the
   solids for what could be counted on.

   The vocabulary shrinks with it. Seven states at five days is a precision the
   model cannot cover, so out here there are three — reaches the gate, big, or
   under it — and the green is the modest one. Nothing past the seam says "On".

   Written as alpha in the fill rather than as `opacity`, because the two-foot
   veil is laid OVER these marks and a second opacity on the mark itself would
   compound into the chart of ghosts this file has already been burned by. */
.lcs-strip__span[data-far-st="gate"]  { fill: var(--s-go-s); }
.lcs-strip__span[data-far-st="big"]   { fill: var(--s-no-s); }
.lcs-strip__span[data-far-st="quiet"] { fill: var(--s-quiet-s); }
.lcs-strip__reach[data-far-st="gate"]  { fill: var(--s-go-r); }
.lcs-strip__reach[data-far-st="big"]   { fill: var(--s-no-r); }
.lcs-strip__reach[data-far-st="quiet"] { fill: var(--s-quiet-r); }
/* A block with no daylight in it cannot be a session, so it is held back the way
   a night hour is. */
.lcs-strip__span[data-day="0"]  { fill: var(--s-quiet-r); }
.lcs-strip__reach[data-day="0"] { fill: rgba(138, 139, 146, .1); }

/* Framed, because on most days every cell is the palest step of the ramp and an
   unframed pale strip on paper reads as a gap rather than as a measurement. */
.lcs-ribbon {
  display: block;
  width: 100%;
  height: 15px;
  margin: 3px 0 0;
  border: 1px solid var(--s-frame);
}
.lcs-ribbon__c[data-b="chop"] { fill: var(--s-b1); }
.lcs-ribbon__c[data-b="wind"] { fill: var(--s-b2); }
.lcs-ribbon__c[data-b="grnd"] { fill: var(--s-b3); }
.lcs-ribbon__c[data-b="long"] { fill: var(--s-b4); }
.lcs-ribbon__c[data-b="rare"] { fill: var(--s-b5); }
/* The eight-second channel. The empty track is drawn across the whole axis so
   the threshold exists on a flat day as well as a good one; the fill is the same
   ink as the two-foot rule above it, because it is the same kind of statement. */
.lcs-ribbon__track { fill: rgba(45,46,51,.13); pointer-events: none; }
.lcs-ribbon__gate  { fill: var(--s-ink); opacity: .78; pointer-events: none; }
/* The ribbon carries the seam too, so the boundary is one line through both marks
   rather than a break that appears in the top chart and not the bottom one. */
.lcs-ribbon__fold  { stroke: rgba(45,46,51,.32); stroke-width: 1; vector-effect: non-scaling-stroke;
                     pointer-events: none; }

.lcs-strip__wins { display: flex; flex-wrap: wrap; gap: 6px 10px; margin: 10px 0 0; }
.lcs-strip__win {
  padding: 4px 10px;
  background: var(--s-go);
  color: #fff;
  font: 500 10.5px/1.4 var(--s-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
/* A window past the seam is a plan, not a session, and it should not sit on the
   page with the same weight as one you could leave for now. Outline where the
   near ones are filled — the same distinction the marks above it make. */
.lcs-strip__win[data-far="true"] {
  background: none;
  color: var(--s-go);
  box-shadow: inset 0 0 0 1px var(--s-go-s);
}
/* The ceiling line, in the slot the window chips would occupy. Not a chip: a
   chip is a thing you can go to, and this is the reason there is nothing to go
   to. So it is set as a sentence, with the seconds in the display serif at the
   size the rest of the page gives a reading — because on this page the number a
   reader is being taught to weigh is always the period. */
.lcs-strip__tops {
  margin: 11px 0 0;
  font: 500 12.5px/1.5 var(--s-sans);
  color: var(--s-muted);
}
.lcs-strip__tops strong {
  font: 400 16.5px/1 var(--s-serif);
  font-variant-numeric: tabular-nums;
  color: var(--s-ink);
}
/* A good week can hold ten windows on one beach, and ten green chips under seven
   beaches stops meaning "here is the window". The rest are counted rather than
   listed, and counted quietly — this is a tally, not a fourth thing to press. */
.lcs-strip__more {
  align-self: center;
  font: 500 10.5px/1.4 var(--s-sans);
  letter-spacing: .06em;
  color: var(--s-muted);
}
/* The seam, said once in words. It sits with the key because that is where this
   page names its marks, and it is one sentence because the chart is meant to have
   already made the point. */
.lcs-regnote { max-width: 74ch; margin-top: 18px; }

/* ------------------------------------------------------------------ tooltip ==
   The one element on this page that is NOT inside #lc-surf: it is appended to
   the body so it can escape the strip's overflow and sit over the sticky header.
   Which means none of the --s-* tokens above reach it — they are declared on
   #lc-surf — and every one of them silently resolved to nothing, leaving white
   type on a transparent panel set in the theme's serif. So the tooltip states
   its own values, taking the theme's variable where there is one and a literal
   where there is not. */
.lcs-tip {
  position: absolute;
  z-index: 980;
  display: none;
  min-width: 210px;
  padding: 10px 13px;
  background: var(--gd-well, #14161a);
  color: #fff;
  font: 500 11.5px/1.55 'Montserrat', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  box-shadow: 0 8px 22px rgba(20,22,26,.28);
}
.lcs-tip strong { display: block; font-weight: 500; letter-spacing: .04em; }
.lcs-tip span { display: block; color: rgba(255,255,255,.66); }
.lcs-tip__v { margin-top: 5px; letter-spacing: .14em; text-transform: uppercase; font-size: 10px; }
.lcs-tip__v[data-st="firing"] { color: #1f9b73 !important; }
.lcs-tip__v[data-st="big"] { color: #e35862 !important; }

/* ------------------------------------------------------------- table view ==*/
.lcs-details { margin: 22px 0 0; }
.lcs-details > summary {
  cursor: pointer;
  font: 500 10.5px/1.5 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-details > summary:hover { color: var(--s-accent); }
.lcs-table { width: 100%; margin: 14px 0 0; border-collapse: collapse; }
.lcs-table caption {
  padding: 0 0 10px;
  text-align: left;
  font: 500 10.5px/1.6 var(--s-sans);
  color: var(--s-muted);
  max-width: 70ch;
}
.lcs-table th, .lcs-table td {
  padding: 7px 12px 7px 0;
  border-bottom: 1px solid var(--s-line);
  text-align: left;
  font: 500 12.5px/1.4 var(--s-sans);
  color: var(--s-ink);
}
.lcs-table th { color: var(--s-muted); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; }
.lcs-table tbody th { font-size: 12.5px; letter-spacing: 0; text-transform: none; color: var(--s-ink); }
/* The seam, in the table. The chart declares its change of register with a rule
   and a change of mark; the numbers declare it with a rule and a change of tone,
   so a reader who arrives here instead of at the chart is told the same thing. */
.lcs-table__far { border-top: 1px solid var(--s-frame); }
.lcs-table__far td { color: var(--s-muted); }
.lcs-num { font-variant-numeric: tabular-nums; }

/* ================================================================= the year ==
   Twelve bars of measured constants, server-rendered. The seven empty months are
   the content, so an empty month is DRAWN — a tick on the baseline under its name
   — rather than left as absence, which a reader would take for missing data. */
.lcs-year { margin: 0; }
.lcs-year__svg { display: block; width: 100%; height: auto; max-width: 860px; }
.lcs-year__bar  { fill: var(--s-go); }
.lcs-year__zero { fill: var(--s-ink); opacity: .22; }
.lcs-year__base { stroke: var(--s-frame); stroke-width: 1; }
.lcs-year__grid { stroke: var(--s-line); stroke-width: 1; }
.lcs-year__gl   { fill: var(--s-muted); font: 500 10px var(--s-sans); text-anchor: end; }
.lcs-year__v    { fill: var(--s-go); font: 500 13px var(--s-sans); text-anchor: middle; font-variant-numeric: tabular-nums; }
.lcs-year__m    { fill: var(--s-muted); font: 500 11px var(--s-sans); text-anchor: middle; letter-spacing: .1em; }
.lcs-year__m[data-now="true"] { fill: var(--s-accent); }
.lcs-year__brk  { fill: none; stroke: var(--s-frame); stroke-width: 1; }
.lcs-year__an   { fill: var(--s-muted); font: 500 10px var(--s-sans); text-anchor: middle; letter-spacing: .18em; text-transform: uppercase; }
.lcs-year__an--end { text-anchor: end; }
.lcs-year__cap {
  margin: 10px 0 0;
  font: 500 10.5px/1.6 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--s-muted);
}

/* The chart is capped at 860 because the SVG scales its own type with its box:
   stretched to the full 1200 measure the month names arrive at 18px and the
   axis stops looking drawn. That cap left 340px of empty paper beside the one
   graphic on the page that carries an argument, and the two paragraphs stating
   that argument sat underneath it where the eye has already left.
   So the reading goes beside the chart instead: "seven months produced nothing
   at all" now sits level with the seven flat months it is about. The section
   only splits where the rail can hold a real measure — below that the stacked
   order is the right one and stays. */
@media (min-width: 1200px) {
  #lc-surf .lcs-sec:has(> .lcs-year) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    /* The chart spans to the last track and the last track absorbs whatever
       height it has left over, so the two paragraphs sit one under the other at
       the top of the rail instead of being spaced out to the chart's baseline. */
    grid-template-rows: auto auto auto 1fr;
    column-gap: 56px;
    align-items: start;
  }
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-head { grid-column: 1 / -1; grid-row: 1; }
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-year { grid-column: 1; grid-row: 2 / -1; }
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-standfirst { grid-column: 2; max-width: none; }
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-standfirst--after { grid-row: 2; margin-top: 0; }
  /* The gate table belongs to the chart, so it stays under the chart. Left to
     auto-placement it lands in the rail and cuts the reading in half. */
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-details { grid-column: 1; grid-row: 5; }
  /* The rail carries the finding, so it is set as one — a shade smaller than
     running text, on the chart's own top line. */
  #lc-surf .lcs-sec:has(> .lcs-year) > .lcs-standfirst { font-size: 15.5px; line-height: 1.7; }
}

/* ================================================================== buoys ==
   A connected pair on one scale rather than two numbers in two boxes: the finding
   is a difference — what an instrument forty miles out reads against what the
   model says at the beach — so the difference is the mark, and the gap between
   the dots is the shelf doing its work. */
.lcs-buoy { padding: 26px 0; border-top: 1px solid var(--s-line); }
.lcs-buoy:first-child { border-top: 0; padding-top: 4px; }
.lcs-buoy__h { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.lcs-buoy__t { margin: 0; font-family: var(--s-serif); font-size: 21px; font-weight: 400; color: var(--s-ink); }
.lcs-buoy__m { margin: 0; font: 500 10.5px/1.6 var(--s-sans); letter-spacing: .12em; text-transform: uppercase; color: var(--s-muted); }
/* Bounded rather than page-wide: the finding is a difference of about a second on
   a fourteen-second scale, and stretched across 1200px that difference stops
   being a length anybody can see. */
.lcs-buoy__plot { position: relative; margin: 22px 0 0; max-width: 620px; }
.lcs-buoy__track {
  position: relative;
  height: 26px;
  border-bottom: 1px solid var(--s-line);
}
.lcs-buoy__link {
  position: absolute;
  top: 12px;
  height: 2px;
  background: var(--s-ink);
  opacity: .28;
}
.lcs-buoy__pin {
  position: absolute;
  top: 6px;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  border-radius: 50%;
}
.lcs-buoy__pin[data-k="measured"] { background: var(--s-ink); }
.lcs-buoy__pin[data-k="model"] { background: #fff; box-shadow: inset 0 0 0 2px var(--s-ink); }
.lcs-buoy__sc { position: relative; height: 18px; margin: 0; }
.lcs-buoy__sc span {
  position: absolute;
  top: 0;
  width: 1px;
  height: 4px;
  background: var(--s-line);
  font: 500 9.5px/1 var(--s-sans);
  letter-spacing: .1em;
  color: var(--s-muted);
  font-variant-numeric: tabular-nums;
}
.lcs-buoy__sc span[data-major] {
  height: 6px;
  background: var(--s-frame);
  text-indent: -3px;
  padding-top: 9px;
  white-space: nowrap;
}
.lcs-buoy__scl {
  margin: 4px 0 0;
  font: 500 9.5px/1.5 var(--s-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--s-muted);
}
/* Capped to the plot's own width so the scale, the two dots and the two
   readings under them read as one instrument instead of a chart with a table
   drifting away from it. */
.lcs-buoy__two {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  margin: 14px 0 0;
  max-width: 620px;
}
.lcs-buoy__c { padding-top: 12px; border-top: 1px solid var(--s-line); }
.lcs-buoy__cl {
  display: block;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-buoy__cl::before {
  content: '';
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 8px;
  border-radius: 50%;
  vertical-align: -1px;
}
.lcs-buoy__c[data-k="measured"] .lcs-buoy__cl::before { background: var(--s-ink); }
.lcs-buoy__c[data-k="model"] .lcs-buoy__cl::before { background: #fff; box-shadow: inset 0 0 0 1.5px var(--s-ink); }
.lcs-buoy__cv { margin: 6px 0 0; font-variant-numeric: tabular-nums; }
.lcs-buoy__cv strong { font-family: var(--s-serif); font-weight: 400; font-size: 30px; line-height: 1; color: var(--s-ink); }
.lcs-buoy__cv i { margin-left: 2px; font: 500 11px var(--s-sans); font-style: normal; color: var(--s-muted); }
.lcs-buoy__cv em {
  display: block;
  margin-top: 4px;
  font: 500 11px/1.5 var(--s-sans);
  font-style: normal;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-buoy__note { margin: 16px 0 0; max-width: 62ch; font-size: 15px; line-height: 1.6; color: var(--s-ink); }
.lcs-buoy__ww { margin: 7px 0 0; max-width: 62ch; font: 500 12px/1.6 var(--s-sans); color: var(--s-muted); }
.lcs-buoy__src {
  display: inline-block;
  margin: 12px 0 0;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--s-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--s-line);
}
.lcs-buoy__src:hover { color: var(--s-accent); }

/* =================================================================== tide ==
   Its own chart on the same time axis, never a second scale on the wave chart.
   The curve is context; the named turning points are the content, because a
   height above mean sea level in metres is not what anybody came for. */
/* Height carries the whole reading. Across 1200px a 46px box flattens six
   tide cycles into a ripple, and a curve with no amplitude says nothing about
   a coast where low water is what opens the bars up. Deeper box, firmer line,
   and the water under it tinted rather than a wash. */
.lcs-tide__svg { display: block; width: 100%; height: 74px; }
.lcs-tide__line { fill: none; stroke: var(--s-ink); stroke-width: 1.5; opacity: .72; vector-effect: non-scaling-stroke; }
.lcs-tide__fill { fill: var(--s-ink); opacity: .075; }
/* Eight turning points will not fit on one line at any page width, and as a
   wrapped flex row the overflow lands as a single orphan under a full line.
   As a grid they wrap into columns instead, which is what a tide table is. */
.lcs-tide__marks {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 9px 24px;
  margin: 14px 0 0;
}
.lcs-tide__mark {
  font: 500 10.5px/1.5 var(--s-sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--s-muted);
  font-variant-numeric: tabular-nums;
}
.lcs-tide__mark[data-k="High"] { color: var(--s-ink); }
.lcs-tide__mark::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 8px;
  background: var(--s-quiet);
}
.lcs-tide__mark[data-k="High"]::before { background: var(--s-ink); }
/* The note gains a present tense when the groins are actually under water — a
   general warning is read once and then never again. It carries the live hatch
   because that is what it is: this water is dangerous right now. */
#lcs-groin[data-live="true"] { color: var(--s-ink); }
#lcs-groin[data-live="true"]::before {
  content: '';
  display: block;
  width: 46px;
  height: 4px;
  margin: 0 0 9px;
  background: repeating-linear-gradient(135deg, var(--s-no) 0 3px, transparent 3px 6px);
}
.lcs-groin__now { display: block; margin-top: 5px; color: var(--s-no); }

/* ============================================================== the spots ==
   Editorial, so it is set as editorial: the live glyph, the name, the sourced
   description, the published rule and the hazard. Not seven boxes. */
.lcs-spot {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 34px;
  padding: 28px 0;
  border-top: 1px solid var(--s-line);
}
.lcs-spot:first-of-type { border-top: 0; }
.lcs-spot__fig { margin: 0; }
.lcs-spot__now { display: grid; gap: 3px; margin-top: 11px; }
.lcs-spot__nowv {
  font: 500 12.5px/1.4 var(--s-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: .06em;
  color: var(--s-ink);
}
.lcs-spot__noww {
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-spot__now[data-st="firing"] .lcs-spot__noww { color: var(--s-go); }
.lcs-spot__now[data-st="big"] .lcs-spot__noww { color: var(--s-no); }
.lcs-spot__t {
  margin: 0;
  font-family: var(--s-serif);
  font-size: 25px;
  font-weight: 400;
  line-height: 1.15;
  color: var(--s-ink);
}
.lcs-spot__m {
  margin: 5px 0 0;
  font: 500 10.5px/1.5 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-spot__p { margin: 14px 0 0; max-width: 62ch; font-size: 15.5px; line-height: 1.66; color: var(--s-ink); }

/* A published rule is not a hazard, and it does not get the hazard's texture.
   The page spends exactly one texture on danger, and spending it on a parking
   regulation would spend it. */
.lcs-access { margin: 16px 0 0; padding: 12px 0 0 16px; border-left: 1px solid var(--s-frame); }
.lcs-access__l {
  display: block;
  margin: 0 0 4px;
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-access p { margin: 0; max-width: 60ch; font: 500 13.5px/1.6 var(--s-sans); color: var(--s-ink); }

/* A PERMANENT hazard: a fact about a place, true whatever the ocean is doing —
   the currents at the Washout, the absence of anybody watching at Hunting Island.
   It is set in the danger red and it is deliberately NOT hatched.
   ⚠ The 135-degree hatch on this page means one thing and one thing only: this
   water is dangerous RIGHT NOW. Spending that texture on a permanent note would
   spend it, and the live warning would then be indistinguishable from a fixture
   a reader has already scrolled past a dozen times. Solid rule here, hatch there;
   the difference is the difference between "always" and "today". */
.lcs-hazard { margin: 16px 0 0; padding: 13px 0 0; }
.lcs-hazard::before {
  content: '';
  display: block;
  width: 46px;
  height: 2px;
  margin: 0 0 11px;
  background: var(--s-no);
}
.lcs-hazard__l {
  display: block;
  margin: 0 0 5px;
  font: 500 10px/1.4 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--s-no);
}
.lcs-hazard p { margin: 0; max-width: 62ch; font-size: 15px; line-height: 1.62; color: var(--s-ink); }

/* The ordinance applies to the island rather than to one break, so it is its own
   object below the three Folly entries: a definition list, because a rule that
   changes by date is a lookup and not a paragraph. */
.lcs-rule { margin: 26px 0 0; padding: 26px 30px; background: var(--s-paper); border: 1px solid var(--s-frame); }
.lcs-rule__t { margin: 0 0 16px; font-family: var(--s-serif); font-size: 21px; font-weight: 400; color: var(--s-ink); }
.lcs-rule__dl { margin: 0; }
.lcs-rule__dl > div {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 4px 26px;
  padding: 11px 0;
  border-top: 1px solid var(--s-line);
}
.lcs-rule__dl > div:first-child { border-top: 0; padding-top: 0; }
.lcs-rule__dl dt {
  margin: 0;
  font: 500 11px/1.6 var(--s-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-rule__dl dd { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--s-ink); }
.lcs-rule__src {
  margin: 16px 0 0;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-noguide {
  margin: 28px 0 0;
  padding: 16px 0 0;
  max-width: 68ch;
  border-top: 1px solid var(--s-line);
  font: 500 13px/1.7 var(--s-sans);
  color: var(--s-muted);
}
.lcs-noguide strong { color: var(--s-ink); letter-spacing: .02em; }

/* ================================================================== cams ==
   The page's photography, and it is the actual beach rather than a stock picture
   of one. Each cam rests as a live still and goes to video on request, so the
   band is useful before anything is pressed and a phone on cellular is never made
   to open three streams.

   Where an operator publishes no still, the plate is not an apology for a missing
   image: it is a drawn horizon carrying that beach's live reading, which is
   something the two photographic frames beside it do not have. A blank dark
   rectangle beside two live pictures reads as broken; a data plate reads as a
   decision.

   The credit is part of the component. It is always present, always a link to
   that camera's own page, and it is what a refused iframe degrades to. */
/* The three frames share a top edge. Whichever cam has the longest credit sets
   the row height, and without the explicit fill the other two settle against
   the bottom of it — which lands 20px of the grid's own hairline colour above
   two of the three photographs and puts three captions on three baselines. A
   triptych that does not line up reads as a loading fault, not a decision. */
.lcs-cams {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  gap: 1px;
  background: rgba(255,255,255,.12);
}
/* The margin reset is the whole fix, not housekeeping. Each cam is a <figure>,
   and the theme's base gives every figure that follows a sibling 20px of
   margin-top plus 20px of margin-bottom. Inside a three-column grid that put
   the second and third photographs 20px below the first and left a dead strip
   under the band — a triptych out of register, from a rule written for prose. */
.lcs-cam {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  margin: 0;
  background: var(--s-well);
}
.lcs-cam__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: linear-gradient(180deg, #1b1f24 0%, #14161a 58%, #191c21 100%);
}
.lcs-cam__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(.92) contrast(1.04);
}
.lcs-cam[data-still-ok="false"] .lcs-cam__still { display: none; }
.lcs-cam__frame iframe,
.lcs-cam__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: #000;
  object-fit: cover;
}
.lcs-cam__plate {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 10px;
  padding: 20px;
  text-align: center;
}
.lcs-cam__plate::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 62%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.22) 18%, rgba(255,255,255,.22) 82%, transparent);
}
.lcs-cam__plate-n,
.lcs-cam__plate-m {
  position: relative;
  font: 500 10px/1.6 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255,255,255,.42);
}
/* The reading is the plate's content, so it is set at the size of a reading and
   not at the size of a caption. */
.lcs-cam__plate-read {
  position: relative;
  font-family: var(--s-serif);
  font-size: 26px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,.9);
}
.lcs-cam[data-plate="photo"] .lcs-cam__plate-read { display: none; }
.lcs-cam[data-st="firing"] .lcs-cam__plate-read { color: var(--s-go-d); }
.lcs-cam[data-live="true"] .lcs-cam__plate,
.lcs-cam[data-live="true"] .lcs-cam__still { display: none; }

.lcs-cam__play {
  position: absolute;
  z-index: 3;
  left: 14px;
  bottom: 14px;
  padding: 9px 16px;
  border: 0;
  border-radius: 0;
  background: rgba(20,22,26,.82);
  backdrop-filter: blur(6px);
  color: #fff;
  font: 500 10px/1 var(--s-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease;
}
.lcs-cam__play:hover { background: var(--s-accent); }
.lcs-cam__play:disabled { cursor: default; opacity: .8; }
.lcs-cam[data-live="true"] .lcs-cam__play { background: rgba(20,22,26,.62); }
.lcs-cam[data-live="true"] .lcs-cam__play::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--s-no-d);
  vertical-align: 1px;
}
.lcs-cam__fail {
  position: absolute;
  z-index: 4;
  inset: auto 14px 52px 14px;
  margin: 0;
  font: 500 11px/1.5 var(--s-sans);
  color: rgba(255,255,255,.8);
  text-align: left;
}
.lcs-cam:not([data-live="failed"]) .lcs-cam__fail { display: none; }
.lcs-cam[data-live="failed"] .lcs-cam__plate { display: grid; }

.lcs-cam__cap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 14px;
  padding: 13px 16px 15px;
}
.lcs-cam__what { margin: 0; font-size: 13.5px; line-height: 1.5; color: rgba(255,255,255,.72); }
.lcs-cam__what strong { display: block; font-family: var(--s-serif); font-size: 17px; font-weight: 400; color: #fff; }
.lcs-cam__src {
  flex: none;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,.24);
  transition: color .2s ease, border-color .2s ease;
}
.lcs-cam__src:hover { color: #fff; border-bottom-color: var(--s-accent); }

/* ================================================================= alerts ==*/
.lcs-alertband { position: relative; background: var(--s-well); color: #fff; }
.lcs-alert {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 48px;
  padding: 54px 0 58px;
}
.lcs-alert__t {
  margin: 0;
  font-family: var(--s-serif);
  font-size: 34px;
  font-weight: 400;
  line-height: 1.14;
  color: #fff;
  text-wrap: balance;
}
.lcs-alert__p { margin: 14px 0 0; max-width: 40ch; font-size: 15px; line-height: 1.65; color: rgba(255,255,255,.68); }
.lcs-alert__held {
  margin: 18px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid rgba(255,255,255,.16);
  max-width: 40ch;
  font: 500 11.5px/1.6 var(--s-sans);
  color: rgba(255,255,255,.52);
}

/* The promise, shown rather than described. A subscriber reading "we'll tell you"
   is being asked to trust a claim; a subscriber reading the actual line, at the
   actual length, is being shown one. */
.lcs-spec {
  margin: 26px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid rgba(255,255,255,.16);
  max-width: 44ch;
}
.lcs-spec__l {
  margin: 0 0 10px;
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255,255,255,.42);
}
.lcs-spec__b {
  margin: 0;
  padding: 13px 15px;
  background: rgba(255,255,255,.06);
  font: 500 13px/1.55 var(--s-sans);
  color: rgba(255,255,255,.82);
}
.lcs-spec__b strong {
  display: block;
  margin-bottom: 3px;
  font-family: var(--s-serif);
  font-weight: 400;
  font-size: 16px;
  color: #fff;
}
.lcs-spec__m { margin: 10px 0 0; font: 500 11px/1.65 var(--s-sans); color: rgba(255,255,255,.42); }

.lcs-field { margin: 0 0 26px; }
.lcs-field > .lcs-label { display: block; margin: 0 0 10px; color: rgba(255,255,255,.5); }
.lcs-field__m { margin: 10px 0 0; font: 500 11px/1.6 var(--s-sans); color: rgba(255,255,255,.42); }
.lcs-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.lcs-chip {
  padding: 10px 16px;
  border: 1px solid rgba(255,255,255,.26);
  border-radius: 0;
  background: transparent;
  color: rgba(255,255,255,.76);
  font: 500 11px/1 var(--s-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.lcs-chip:hover { border-color: rgba(255,255,255,.6); color: #fff; }
.lcs-chip[aria-pressed="true"] { background: #fff; border-color: #fff; color: var(--s-ink); }

/* The threshold control is the best idea available to this page, so it is not a
   row of pills. The number that sells it is not the seconds — it is how seldom
   each floor actually fired, which turns the rarity into the product instead of
   something to apologise for. So the frequency gets the display face and every
   option states the silence it buys. */
.lcs-secs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; background: rgba(255,255,255,.2); }
.lcs-secpick {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 2px 14px;
  width: 100%;
  padding: 15px 18px 16px;
  border: 0;
  border-radius: 0;
  background: var(--s-well);
  text-align: left;
  cursor: pointer;
  transition: background .18s ease;
}
.lcs-secpick:hover { background: #1d2027; }
.lcs-secpick[aria-pressed="true"] { background: #fff; }
.lcs-secpick__n {
  grid-row: 1 / span 2;
  font-family: var(--s-serif);
  font-size: 34px;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.lcs-secpick__n i {
  margin-left: 1px;
  font: 500 11px var(--s-sans);
  font-style: normal;
  color: rgba(255,255,255,.5);
}
.lcs-secpick__l { font: 500 12.5px/1.4 var(--s-sans); color: rgba(255,255,255,.8); }
.lcs-secpick__d {
  font: 500 10px/1.5 var(--s-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--s-go-d);
}
.lcs-secpick[aria-pressed="true"] .lcs-secpick__n { color: var(--s-ink); }
.lcs-secpick[aria-pressed="true"] .lcs-secpick__n i { color: var(--s-muted); }
.lcs-secpick[aria-pressed="true"] .lcs-secpick__l { color: var(--s-ink); }
.lcs-secpick[aria-pressed="true"] .lcs-secpick__d { color: var(--s-go); }

.lcs-input {
  width: 100%;
  max-width: 420px;
  margin: 10px 0 0;
  padding: 13px 15px;
  border: 1px solid rgba(255,255,255,.26);
  border-radius: 0;
  background: rgba(255,255,255,.05);
  color: #fff;
  font: 500 14.5px/1.4 var(--s-sans);
}
.lcs-input::placeholder { color: rgba(255,255,255,.36); opacity: 1; }
.lcs-input:focus { outline: none; border-color: #fff; background: rgba(255,255,255,.1); }
.lcs-consent { margin: 9px 0 0; max-width: 52ch; font: 500 11px/1.6 var(--s-sans); color: rgba(255,255,255,.46); }

.lcs-alert__go {
  padding: 15px 30px;
  border: 0;
  border-radius: 0;
  background: #fff;
  color: var(--s-ink);
  font: 500 11px/1 var(--s-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.lcs-alert__go:hover { background: var(--s-accent); color: #fff; }
.lcs-alert__go:disabled { background: rgba(255,255,255,.34); color: var(--s-well); cursor: default; }
.lcs-alert__go[data-busy] { position: relative; color: transparent; }
.lcs-alert__go[data-busy]::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 14px;
  height: 14px;
  border: 2px solid rgba(20,22,26,.3);
  border-top-color: var(--s-well);
  border-radius: 50%;
  animation: lcs-spin .7s linear infinite;
}
@keyframes lcs-spin { to { transform: rotate(360deg); } }

#lcs-alert-msg { margin: 14px 0 0; font: 500 13px/1.6 var(--s-sans); min-height: 1.6em; }
#lcs-alert-msg[data-kind="error"] { color: var(--s-no-d); }
#lcs-alert-msg[data-kind="ok"] { color: var(--s-go-d); }
.lcs-alert[data-done="true"] .lcs-alert__form { opacity: .45; pointer-events: none; }

/* ================================================================== tail ==*/
.lcs-links { margin: 0; padding: 0; list-style: none; }
.lcs-links li { border-bottom: 1px solid var(--s-line); }
.lcs-links a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 14px 0;
  font-family: var(--s-serif);
  font-size: 19px;
  color: var(--s-ink);
  text-decoration: none;
  transition: color .2s ease;
}
.lcs-links a:hover { color: var(--s-accent); }
.lcs-links em {
  flex: 0 1 auto;
  text-align: right;
  font: 500 10.5px/1.5 var(--s-sans);
  font-style: normal;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--s-muted);
}
.lcs-colophon { margin: 30px 0 0; max-width: 88ch; font: 500 11px/1.75 var(--s-sans); color: var(--s-muted); }
.lcs-colophon a { color: var(--s-muted); border-bottom: 1px solid var(--s-line); text-decoration: none; }
.lcs-colophon a:hover { color: var(--s-accent); }
/* Provenance, one step quieter than the colophon: a reader who wants to check a
   rule needs it findable, and nobody else needs it at all. */
.lcs-sources {
  margin: 14px 0 0;
  max-width: 88ch;
  font: 500 10.5px/1.75 var(--s-sans);
  color: var(--s-muted);
  opacity: .8;
}
.lcs-sources a { color: inherit; border-bottom: 1px solid var(--s-line); text-decoration: none; }
.lcs-sources a:hover { color: var(--s-accent); }
.lcs-standfirst--after { margin-top: 24px; }

/* ============================================================== skeletons ==
   The shape of the answer, not a spinner in the middle of it. */
#lc-surf[data-loaded="loading"] #lcs-verdict { min-height: 240px; }
#lc-surf[data-loaded="loading"] #lcs-sea { min-height: 250px; }
#lc-surf[data-loaded="loading"] #lcs-rows::after,
#lc-surf[data-loaded="loading"] #lcs-strips::after {
  content: '';
  display: block;
  height: 320px;
  background: linear-gradient(90deg, rgba(45,46,51,.05) 0 30%, rgba(45,46,51,.09) 45%, rgba(45,46,51,.05) 60%);
  background-size: 220% 100%;
  animation: lcs-sweep 1.25s linear infinite;
}
#lc-surf[data-loaded="loading"] #lcs-strips::after { height: 460px; }
@keyframes lcs-sweep { to { background-position: -120% 0; } }
#lc-surf[data-loaded="loading"] #lcs-legend,
#lc-surf[data-loaded="loading"] .lcs-details { visibility: hidden; }

/* ============================================================= breakpoints ==*/
@media (max-width: 1199px) {
  .lcs-verdict { grid-template-columns: minmax(0, 1fr) 300px; gap: 22px 36px; }
  .lcs-row { grid-template-columns: 96px minmax(0, 1fr) 66px 64px 52px 66px 60px 92px; gap: 0 12px; }
  .lcs-rowaxis { grid-template-columns: 96px minmax(0, 1fr); gap: 0 12px; }
  .lcs-meter { width: 96px; }
  .lcs-head__t { font-size: 24px; }
  .lcs-rule__dl > div { grid-template-columns: 200px minmax(0, 1fr); gap: 4px 20px; }
}

@media (max-width: 959px) {
  .lcs-verdict { grid-template-columns: minmax(0, 1fr); gap: 24px; padding-bottom: 26px; }
  .lcs-mix { border-top: 1px solid rgba(255,255,255,.18); }
  .lcs-alert { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .lcs-cams { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lcs-spot { grid-template-columns: 140px minmax(0, 1fr); gap: 24px; }
  .lcs-meter--big { width: 112px; }
  .lcs-sea__cap { padding: 0 20px 18px; }
  .lcs-buoy__two { gap: 16px; }
}

@media (max-width: 767px) {
  /* The row stops being a table and becomes a record in two tiers. Same DOM
     order, so the tab order never jumps backwards.

     The earlier arrangement put the three measurements on one line THROUGH the
     name and glyph columns, which set "SE / 126°" under the waveform and "1.4 /
     FT SWELL" inside the beach's own name block. Every figure then read as
     belonging to whatever sat above it, and a board whose entire job is
     comparison arrived as four lines of unattached numbers.

     Now: tier one is who and how long — glyph, name, the period at display
     size, the state word under it. Tier two is the three supporting figures on
     one baseline in equal columns, indented past the glyph so the whole record
     hangs off a single left edge. The wind bar closes it. */
  .lcs-row {
    grid-template-columns: 48px repeat(3, minmax(0, 1fr));
    grid-template-areas: none;
    gap: 0 12px;
    padding: 15px 14px 14px;
  }
  /* The measure takes the full width here rather than hiding in the margin
     column. Squeezed into 76px beside the beach name it was the quietest mark on
     a card whose loudest was the wind bar — the page's whole argument whispered
     under its own modifier. Across the card it is the same instrument as the one
     on the board, at a width where the rule at eight is unmissable, and it sits
     directly under the figure it explains. */
  .lcs-row__m    { grid-column: 1 / -1; grid-row: 3; margin-top: 13px; }
  .lcs-meter     { width: auto; }
  .lcs-row__name { grid-column: 2 / 4; grid-row: 1; }
  .lcs-row__p    { grid-column: 4; grid-row: 1; justify-self: end; align-self: start; }
  /* The verdict word rides directly under its own number rather than at the far
     side of a line it has nothing to do with. It takes two columns because
     "Worth a look" is wider than "5.4 s" and must not break across lines. */
  .lcs-row__word { grid-column: 3 / -1; grid-row: 2; justify-self: end; margin-top: 5px; }
  /* Column one stays empty here on purpose: the measure hangs in a margin and
     the figures line up with the beach name above them. */
  .lcs-row__ft   { grid-column: 2; grid-row: 4; }
  .lcs-row__dir  { grid-column: 3; grid-row: 4; }
  .lcs-row__wind { grid-column: 4; grid-row: 4; }
  .lcs-row__ft, .lcs-row__dir, .lcs-row__wind { margin-top: 15px; align-content: start; }
  .lcs-row__q    { grid-column: 1 / -1; grid-row: 5; margin-top: 13px; }
  .lcs-row__p strong { font-size: 27px; }
  /* The axis stacks. Its tick keeps the same 66.667% as the measures above it,
     so at this width it lands on the same x as every rule on the board. */
  .lcs-rowaxis { grid-template-columns: minmax(0, 1fr); gap: 4px 0; padding: 12px 14px 13px; }

  .lcs-cams { grid-template-columns: minmax(0, 1fr); }
  .lcs-spot { grid-template-columns: minmax(0, 1fr); gap: 14px; padding: 24px 0; }
  .lcs-spot__fig { display: flex; align-items: center; gap: 18px; }
  .lcs-meter--big { width: 104px; flex: none; }
  .lcs-spot__now { margin-top: 0; }
  .lcs-next { grid-template-columns: auto 1fr; }
  .lcs-next__go { grid-column: 1 / -1; grid-row: auto; justify-self: start; margin-top: 12px; }
  .lcs-buoy__two { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .lcs-buoy__c { padding: 12px 0; }
  .lcs-rule { padding: 22px 20px; }
  .lcs-rule__dl > div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  .lcs-secs { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 639px) {
  .lcs-preview { padding: 9px 15px; letter-spacing: .1em; }
  .lcs-head { flex-wrap: wrap; gap: 4px; }
  .lcs-head__t { font-size: 21px; width: 100%; }
  .lcs-head__m { max-width: none; text-align: left; font-size: 10px; letter-spacing: .14em; }
  .lcs-mast { font-size: 10px; letter-spacing: .2em; padding-top: 20px; }
  /* On a phone this paragraph runs to six lines and takes the top third of the
     first screen, which is the screen the verdict has to win in half a second.
     It keeps its words and gives up its weight: set back a step in size and
     tone so the eye lands on the headline and comes back up for the framing. */
  .lcs-lede { margin-top: 14px; font-size: 14.5px; line-height: 1.62; color: rgba(255,255,255,.5); }
  .lcs-verdict { padding: 22px 0 10px; min-height: 0; }
  .lcs-verdict__why { font-size: 15.5px; }
  /* The label stacks above rather than taking a third of a 384px column. */
  .lcs-next { grid-template-columns: minmax(0, 1fr); }
  .lcs-next__l { grid-row: auto; margin-bottom: 8px; }
  /* Same reason, and one more: at 384px a nowrap label beside a running sentence
     leaves the sentence a 250px measure, which is four words a line. */
  .lcs-forming { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 14px 16px 15px; }
  .lcs-forming__t { font-size: 14px; }
  .lcs-next__v, .lcs-next__m { grid-column: 1; }
  .lcs-mix__r { grid-template-columns: minmax(0, 1fr) auto auto; gap: 4px 12px; }
  .lcs-mix__d { grid-column: 1 / -1; text-align: left; }
  .lcs-alert__t { font-size: 27px; }
  .lcs-spot__t { font-size: 21px; }
  /* Taller on a phone, where the strip is a third of the width and the height is
     the only dimension left to read a swell filling in. */
  .lcs-strip__svg { height: 68px; }
  .lcs-axis { height: 32px; }
  .lcs-axis__reg { font-size: 8.5px; letter-spacing: .12em; padding-left: 5px; }
  .lcs-axis__d { font-size: 9.5px; letter-spacing: .1em; padding-left: 5px; }
  .lcs-axis__d[data-far="true"] { letter-spacing: .04em; }
  .lcs-axis__d[data-flip="true"] { padding: 0 5px 0 0; }
  .lcs-links a { font-size: 16.5px; gap: 12px; }
  .lcs-links em { font-size: 9.5px; letter-spacing: .1em; }
  .lcs-sec { margin-bottom: 48px; }
  .lcs-sea__cap { padding: 0 15px 16px; letter-spacing: .1em; }
  .lcs-input { max-width: none; }
  .lcs-alert__go { width: 100%; }
  .lcs-scale__bar { height: 38px; }
  /* Three labels under a 320px rule collide. The tail keeps its own line, which
     is where the argument lives anyway. */
  .lcs-scale__labs { flex-wrap: wrap; }
  .lcs-scale__l { width: 50% !important; padding-right: 10px; }
  .lcs-scale__l--tail { width: 100% !important; margin-top: 10px; }
  .lcs-scale__dl { font-size: 9.5px; letter-spacing: .06em; }
  .lcs-scale__dl strong { font-size: 13px; }
  /* "High tomorrow 2pm" needs the width of half a phone, so the tide table
     runs two abreast and stays a table rather than becoming a ragged list. */
  .lcs-tide__marks { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; }
  .lcs-tide__svg { height: 62px; }
}

@media (prefers-reduced-motion: reduce) {
  #lc-surf *,
  #lc-surf *::before,
  #lc-surf *::after { transition: none !important; animation: none !important; }
  #lc-surf[data-loaded="loading"] #lcs-rows::after,
  #lc-surf[data-loaded="loading"] #lcs-strips::after { background: rgba(45,46,51,.06); }
}

@media (forced-colors: active) {
  /* A box-shadow is dropped outright by a forced palette, so the frame that
     says "the model sees this swell, not the hour it lands" would vanish and
     leave a paragraph running on from the one above it. An outline survives. */
  .lcs-forming { outline: 1px solid CanvasText; outline-offset: -1px; }
  /* Two hues carrying seven states and a five-step ramp cannot survive a forced
     palette, so the words, the hatching and the table view are what remain —
     which is why none of them was ever optional. */
  /* The axis joins the list its own board is already on: forced through the
     system palette its tick and stem flatten to the text colour and stop
     pointing at anything, which leaves the marks above it unnamed. */
  .lcs-row, .lcs-rowaxis, .lcs-strip, .lcs-cam, .lcs-secpick { forced-color-adjust: none; }
  .lcs-strip__bar { fill: CanvasText; }
  .lcs-strip__bar[data-st="firing"] { fill: Highlight; }
  .lcs-ribbon__c { stroke: CanvasText; stroke-width: .5; }
  /* The far mark's whole grammar is two alphas of one hue, and a forced palette
     has no alphas. So it becomes an outline with a solid foot: the shape still
     says "held this much, reached that much" without depending on colour. */
  .lcs-strip__span { fill: CanvasText; }
  .lcs-strip__span[data-far-st="gate"] { fill: Highlight; }
  .lcs-strip__reach { fill: Canvas; stroke: CanvasText; stroke-width: 1; }
  .lcs-strip__fold, .lcs-ribbon__fold { stroke: CanvasText; }
}
