/* Site-only additions on top of outputs/design/components.css (no tokens here: they live in tokens.css). */
.hw-nav__brand { color: var(--hw-ink); display: inline-flex; align-items: center; }
.hw-nav__brand .nav__mark { height: 22px; width: auto; filter: drop-shadow(0 0 10px color-mix(in srgb, var(--hw-electric) 45%, transparent)); }
.hw-nav form { margin: 0; }
.hw-nav__tools > form > .hw-btn { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1080px) {                      /* the menu-button nav's range (D-020, AP20) */
  .hw-nav__brand .nav__mark { height: 18px; }
  .hw-nav__tools > form:not(.hw-lang), .hw-nav__me { display: none; }   /* profile + logout move into the sheet (D-020) */
}
.hw-auth { max-width: 420px; margin-inline: auto; }

/* ── the landing (D-031: the matrix and the logo only) ── */
.hw-hero {
  position: relative; z-index: 1;                /* above the back scene, below the soft front layer */
  display: grid; place-items: center;
  min-height: calc(100vh - var(--hw-nav-h)); padding: var(--hw-space-6) var(--hw-space-5);
  overflow-x: clip;                              /* the logo's beam reaches past the edges by design (AP8 notes) */
}
.hw-hero .hw-logo { width: min(1040px, 84vw); margin: 0; }
@media (max-width: 560px) {
  .hw-hero { min-height: calc(100vh - 56px); padding: var(--hw-space-4); }
  .hw-hero .hw-logo { width: 92vw; }
  /* the countdown component (LAN page, item 6) on phones */
  .hw-countdown { gap: var(--hw-space-2); }
  .hw-countdown__unit { min-width: 0; flex: 1; padding-inline: 0; }
  .hw-countdown__value { font-size: 26px; }
}

/* ── auth and profile (item 3) ── */
.hw-nav__me { max-width: 16ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-nav__me[aria-current="page"] { border-color: var(--hw-electric); box-shadow: 0 0 12px color-mix(in srgb, var(--hw-electric) 30%, transparent); }
/* the user: "Exit button "button" color is same as the current background, hard to see. Button can be also bit bigger."
   It had no fill of its own; now a lit tile in the electric tint, 44 px, a 22 px icon; the hover fills it */
.hw-nav__logout { all: unset; display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: var(--hw-radius-2);
  color: var(--hw-glow); background: color-mix(in srgb, var(--hw-electric) 22%, var(--hw-bg-2)); cursor: pointer; }
.hw-nav__logout svg { width: 22px; height: 22px; }
.hw-nav__logout:hover { color: var(--hw-bg-0); background: var(--hw-electric); }
.hw-nav__logout:focus-visible { outline: 2px solid var(--hw-focus); }
.hw-check-row { display: flex; align-items: center; gap: var(--hw-space-3); min-height: 44px; color: var(--hw-ink); cursor: pointer; }
.hw-check { width: 20px; height: 20px; accent-color: var(--hw-electric); }
.hw-profile { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: var(--hw-space-5); align-items: start; }
.hw-profile__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--hw-space-4); }
.hw-profile__rank { font-size: var(--hw-text-lg); }
.hw-stack > .hw-chip { margin-top: 0; }
@media (max-width: 860px) { .hw-profile { grid-template-columns: 1fr; } }

/* ── members list (item 4, D-003) ── */
.hw-table-wrap { overflow-x: auto; }                 /* a wide table scrolls inside itself, never the page */
.hw-members td:nth-child(2) { font-weight: 600; }                 /* the nick (D-047 put # first) */
.hw-members .hw-rownum { width: 1%; color: var(--hw-ink-3); }       /* D-047: the row's place, narrow and quiet */
.hw-members .hw-rank { white-space: nowrap; }
/* the user: "before log-in keep header as wide as after logged in, but make the columns tighter together" (/members/
   signed out), then "Repeat the concept in LAN page too" → the LANs list. A .hw-tight table stays full width and each
   column hugs its content with a steady gap (--hw-tight-gap). The spare width goes to one column: an empty last one
   (.hw-fill, aria-hidden; /members/) or a real one that may wrap (.hw-flex; the Place on /lans/). .hw-wrapcol lets a
   column wrap inside a set width (the seat map's longest label). */
.hw-tight { --hw-tight-gap: 2.5rem; }
.hw-history.hw-tight { --hw-tight-gap: 1.5rem; }       /* seven columns: a smaller gap */
@media (min-width: 561px) {
  .hw-tight tr > :not(.hw-fill, .hw-flex, .hw-wrapcol) { width: 1%; white-space: nowrap; }
  .hw-tight .hw-fill { width: 100%; }   /* the empty last column takes all the spare width */
  .hw-tight th.hw-wrapcol { width: 9rem; }
  .hw-tight td:not(.hw-fill):not(:first-child), .hw-tight th[data-sort-key]:not(:first-child) button { padding-inline: 0 var(--hw-tight-gap); }
  .hw-tight tr > :last-child, .hw-tight tr > :last-child button { padding-right: 0; }
}
.hw-tight .hw-fill { padding: 0; }
.hw-profile__rank .hw-rank--lg { font-size: var(--hw-text-md); }
@media (max-width: 560px) {
  .hw-table th, .hw-table td { padding-inline: var(--hw-space-2); }
  .hw-table th:first-child, .hw-table td:first-child { padding-left: 0; }
  .hw-table th:last-child, .hw-table td:last-child { padding-right: 0; }
  .hw-members .hw-rank { gap: 5px; font-size: 10px; letter-spacing: .04em; }
  .hw-members td:nth-child(2) { overflow-wrap: anywhere; }   /* D-047: with # first, a long nick breaks in its cell (AP21) */
  .hw-members .hw-rank { white-space: normal; }              /* and a long rank name under its insignia: the table fits */
}

/* ── the LAN page (item 6) ── */
.hw-lan-hero h1 { font-size: var(--hw-text-2xl); margin: 0; text-wrap: balance; overflow-wrap: anywhere; }   /* the user: one row, two at most */
.hw-lan-facts { display: flex; flex-wrap: wrap; gap: var(--hw-space-6); margin-top: var(--hw-space-4); }
.hw-lan-facts .hw-stat > :last-child { color: var(--hw-ink); }
.hw-lan-desc { margin-top: var(--hw-space-5); white-space: normal; font-size: var(--hw-text-md); }   /* the user: a bit smaller */
.hw-lan-body { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: var(--hw-space-5); margin-top: var(--hw-space-6); align-items: start; }
.hw-lan-map { padding: var(--hw-space-4); }
.hw-lan-map [data-seatmap] svg { width: 100%; height: auto; }
.hw-lan-map__head { margin-bottom: var(--hw-space-3); }
.hw-lan-map__head .hw-eyebrow { margin: 0; }
.hw-mapview { gap: var(--hw-space-2); }
.hw-lan-map3d iframe { display: block; width: 100%; height: min(70vh, 620px); border: 0; border-radius: var(--hw-radius-2);
  background: var(--hw-bg-0); }                                  /* the 3D dollhouse (sprint-3 item 3) */
.hw-bookbar__form { flex-wrap: nowrap; width: 100%; gap: var(--hw-space-4); }
.hw-bookbar__help { margin: 0; flex: 1; }
.hw-lan-actions form { margin: 0; }
.hw-lan-body .hw-legend { justify-content: center; }         /* the user: the seat counts centred under the seat map */
/* the user: "Cancel my seat" takes the red outline Unregister had; Unregister (and its "Yes, unregister") is solid red,
   white text: a deeper red than --hw-danger, so white text passes (5.3:1; white on #ff3b4d would be 3.4:1) */
.hw-btn--danger-solid { background: #d1202f; color: #fff; border-color: #d1202f; }
.hw-btn--danger-solid:hover { background: #e02a3a; box-shadow: 0 0 18px color-mix(in srgb, var(--seat-booked) 35%, transparent); }
.hw-chip--error { color: var(--hw-danger); border-color: color-mix(in srgb, var(--seat-booked) 45%, transparent); }
.hw-who__private { font-size: var(--hw-text-xs); color: var(--hw-ink-2); }
.hw-table th button { all: unset; box-sizing: border-box; cursor: pointer; }   /* unset dropped border-box: 100% + padding poked 8 px out (AP21) */
.hw-table th button:focus-visible { outline: 2px solid var(--hw-focus); }
@media (max-width: 860px) {                       /* one column, the map first */
  .hw-lan-body { grid-template-columns: minmax(0, 1fr); }   /* AP21: the participants table never widens the page */
}
@media (max-width: 400px) {                       /* AP21: small phones get a tighter participants panel */
  .hw-lan-body > aside.hw-panel { padding: var(--hw-space-3); }
  .hw-who td, .hw-who th[data-sort-key] button { padding-inline: var(--hw-space-1); }
  .hw-who tr > :first-child, .hw-who tr > :first-child button { padding-left: 0; }
  .hw-who tr > :last-child, .hw-who tr > :last-child button { padding-right: 0; }
  /* D-047: the members table got a # column, so it takes the same tighter cells (fits 375 px with no inner scroll) */
  .hw-members td, .hw-members th[data-sort-key] button { padding-inline: var(--hw-space-1); }
  .hw-members tr > :first-child { padding-left: 0; }
  .hw-members tr > :last-child, .hw-members tr > :last-child button { padding-right: 0; }
}
@media (max-width: 560px) {
  .hw-lan-hero h1 { font-size: var(--hw-text-xl); }
  .hw-bookbar__form { flex-wrap: wrap; }
  .hw-bookbar__form .hw-btn { width: 100%; }
}

[data-login-prompt].is-flash { color: var(--hw-ink); animation: hw-flash 1.2s var(--hw-ease); }
@keyframes hw-flash { 0%, 60% { text-shadow: 0 0 12px var(--hw-glow); } 100% { text-shadow: none; } }

/* ── the Historia list (item 7, D-021): the place is each row's one link and focus stop; tables.js follows a click
   anywhere on the row. Phones drop the games column (the LAN page shows them) ── */
.hw-history tbody tr:has(.hw-history__link) { cursor: pointer; }
.hw-history__link { color: var(--hw-ink); font-weight: 600; }
.hw-history__link:hover { text-decoration: none; }
.hw-history tbody tr:has(.hw-history__link:focus-visible) > td { background: color-mix(in srgb, var(--hw-bg-2) 60%, transparent); }
.hw-history td.hw-num { white-space: nowrap; }
.hw-history td.hw-history__games { color: var(--hw-ink-2); }
@media (max-width: 560px) { .hw-history__games { display: none; } }

/* ── footer and the privacy page (sprint-3 item 4, legal review L1) ── */
.hw-footer { padding: var(--hw-space-6) 0; color: var(--hw-ink-3); font-size: var(--hw-text-sm); }
.hw-footer a { color: var(--hw-ink-2); }
.hw-prose { max-width: 68ch; }
.hw-prose h2 { margin-top: var(--hw-space-6); }

/* ── QA batch (sprint-3 item 5) ── */
.hw-messages { display: flex; flex-wrap: wrap; gap: var(--hw-space-2); margin-top: var(--hw-space-4); }   /* QA-02 */
.hw-messages .hw-chip { margin: 0; }
.hw-confirm > summary { list-style: none; }                                 /* QA-08: a button, no disclosure triangle */
.hw-confirm > summary::-webkit-details-marker { display: none; }
.hw-confirm[open] > summary { box-shadow: 0 0 0 2px var(--hw-danger); }
.hw-confirm__body { margin-top: var(--hw-space-3); max-width: 46ch; padding: var(--hw-space-4); }
.hw-confirm__body p { margin: 0; }
.hw-errorpage { max-width: 560px; margin-inline: auto; }                    /* QA-04 */

@media (max-width: 1080px) {                      /* QA-16: the sheet is opaque (its own colour, the panels' token), so a
                                                     large heading behind it never shows through */
  .hw-nav__sheet[data-open] { background: var(--hw-bg-1); }
}

/* the nav countdown as a link to its LAN (the user's item A) */
a.hw-clock { text-decoration: none; }
/* the user: the hover keeps the cut corners: the chamfer ring (::after, D-080) brightens; a square border would lose the cuts */
a.hw-clock:hover { text-decoration: none; --hw-edge-ring: color-mix(in srgb, var(--hw-accent-2) 75%, transparent); }
a.hw-clock:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: 2px; }


/* the 2D map: a lit seat lights its LED number too (the user: "When block is selected lit also the number in LED
   element"). Your selection, or a seat you clicked (is-lit); while another seat is lit, your selection rests and so do
   its digits (the map's "one lit seat at a time", outputs/svg/svgmap.py). Specificity above the map's own LED rules */
.hw-seatmap:not(:has(.seat.is-lit)) .seat--selected .led-on,
.hw-seatmap .seat.is-lit .led-on { fill: #fff;
  filter: drop-shadow(0 0 2px var(--lit, var(--seat-free-led))) drop-shadow(0 0 5px var(--lit, var(--seat-free-led))); }   /* a clicked free seat has no --lit */
.hw-seatmap:not(:has(.seat.is-lit)) .seat--selected .led-off,
.hw-seatmap .seat.is-lit .led-off { fill-opacity: .2; }

/* the user's member profile pages (members/member_detail.html, lan_history.html) */
.hw-profile__history { margin-top: var(--hw-space-5); }
.hw-lanhist td:first-child { overflow-wrap: anywhere; }
.hw-admin-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--hw-space-2) var(--hw-space-4); margin: 0; }
.hw-admin-facts dt { color: var(--hw-ink-3); font-size: var(--hw-text-sm); }
.hw-admin-facts dd { margin: 0; overflow-wrap: anywhere; }
/* the user: the row of a picked booked / pre-booked seat lights up in the seat's own colour */
.hw-who tr.is-hl-booked > td { background: color-mix(in srgb, var(--seat-booked) 16%, transparent); box-shadow: inset 0 1px 0 var(--seat-booked), inset 0 -1px 0 var(--seat-booked); }
.hw-who tr.is-hl-prebooked > td { background: color-mix(in srgb, var(--seat-prebooked) 14%, transparent); box-shadow: inset 0 1px 0 var(--seat-prebooked), inset 0 -1px 0 var(--seat-prebooked); }
/* the user: "Registered list should be more compact in vertical direction": tighter rows, the same columns */
.hw-who td { padding-block: 3px; line-height: 1.25; }
.hw-who th[data-sort-key] button { padding-block: 6px; }
.hw-who .hw-rank__icon { width: 28px; height: 16px; }
.hw-who__private { line-height: 1.2; }
/* the user: no horizontal scroll in the Registered table: fixed columns, every cell one line, cut at the edge; a cut
   text scrolls slowly after a 1 s rest (static/hiw/scroller.js) */
.hw-who { table-layout: fixed; }
/* the user: "Rank" gets more room, the spot number less; a visitor's spot is "–" (the word on hover and for screen readers) */
.hw-who th:nth-child(2) { width: 144px; }                /* the longest rank (insignia + name) needs 139 px */
/* the user: "Make Nick wider ... move Rank to bit more right. Align Spot values center with SPOT header title and trim
   that column space": Spot 76 → 64 px (Nick takes the 12 px, so Rank moves right); the title and the numbers share
   one centre line, the sort arrow sits on the column's right edge, out of the centring ("PAIKKA" is 48 px) */
.hw-who th:nth-child(3) { width: 64px; }
@media (min-width: 401px) { .hw-who td, .hw-who th[data-sort-key] button { padding-inline: var(--hw-space-2); } }
.hw-who th:nth-child(3) button, .hw-who td:nth-child(3) { padding-inline: 0; }
.hw-table.hw-who th.num:nth-child(3) button { position: relative; justify-content: center; }   /* over th.num's flex-end */
.hw-who th:nth-child(3) button::after { position: absolute; right: 0; }
.hw-table.hw-who td.num:nth-child(3) { text-align: center; }
.hw-who td, .hw-who th { overflow: hidden; }            /* the user: never a horizontal scroll bar here */
.hw-clip { display: block; overflow: hidden; white-space: nowrap; scrollbar-width: none; }
.hw-clip::-webkit-scrollbar { display: none; }
.hw-section--tight { padding-top: var(--hw-space-4); }   /* the user: the LAN page starts right under the nav */
/* the user: the profile's Save is grey while nothing has changed, green once something has */
.hw-save { background: var(--hw-ok); color: #000; border-color: var(--hw-ok); box-shadow: 0 0 18px color-mix(in srgb, var(--seat-free) 30%, transparent); }
.hw-save:hover { filter: brightness(1.08); }
.hw-btn.hw-save[disabled] { opacity: 1; background: var(--hw-bg-2); color: var(--hw-ink-3); border-color: var(--hw-edge-2); box-shadow: none; }
/* the user: "Make members and lan lists a bit more compact in vertical direction": tighter rows; on /lans/ a long
   games list stays on one line and scrolls after a 1 s rest (static/hiw/scroller.js), as the Registered table does */
.hw-members td, .hw-history td { padding-block: 5px; line-height: 1.3; }
.hw-members th[data-sort-key] button, .hw-history th[data-sort-key] button { padding-block: 8px; }
.hw-members .hw-rank__icon { width: 28px; height: 16px; }
.hw-history .hw-clip { max-width: 30ch; }
.hw-stat__value.hw-stat__text { font-size: var(--hw-text-md); overflow-wrap: anywhere; }   /* D-065: free text on a member page */

/* D-063: the x-ray venue map on the LAN page (the frame draws its own black; the credit stays outside the sandbox) */
.hw-geo iframe { display: block; width: 100%; height: min(62vh, 520px); border: 0; border-radius: var(--hw-radius-2); background: var(--hw-bg-0); margin-top: var(--hw-space-2); }
.hw-geo__credit { margin: var(--hw-space-2) 0 0; text-align: right; }
.hw-geo__credit a { color: inherit; }

/* the user: "add some gradient based background to website to give a bit more soul to page": every page but the landing
   (its code rain keeps its black) sits on a slow, dark wash of the brand's light: electric blue from the top left, a
   cyan breath at the top right, a faint pink at the bottom right. Fixed, so it stays put while the page scrolls; the
   panels' own translucent fill lets it through. Kept dark enough that every text contrast stays as it was */
body:not(.hw-landing) {
  background:
    radial-gradient(1100px 700px at 8% -12%, color-mix(in srgb, var(--hw-electric) 20%, transparent), transparent 62%),
    radial-gradient(900px 520px at 96% 4%, color-mix(in srgb, var(--hw-glow) 9%, transparent), transparent 60%),
    radial-gradient(1000px 700px at 100% 108%, color-mix(in srgb, var(--hw-accent) 10%, transparent), transparent 60%),
    linear-gradient(180deg, #02060f 0%, var(--hw-bg-0) 55%);
  background-attachment: fixed;
}
/* D-071: an old LAN description's own markup, cleaned (lans/description.py), in the page's type: small headings,
   tight paragraphs, a plain table */
.hw-lan-desc h2, .hw-lan-desc h3, .hw-lan-desc h4 { font-size: var(--hw-text-lg); margin: var(--hw-space-4) 0 var(--hw-space-2); color: var(--hw-ink); }
.hw-lan-desc h3, .hw-lan-desc h4 { font-size: var(--hw-text-md); }
.hw-lan-desc > :first-child { margin-top: 0; }
.hw-lan-desc p { margin: 0 0 var(--hw-space-3); }
.hw-lan-desc table { border-collapse: collapse; margin: 0 0 var(--hw-space-3); }
.hw-lan-desc td, .hw-lan-desc th { padding: 3px var(--hw-space-3) 3px 0; vertical-align: top; text-align: left; }
.hw-lan-desc ul, .hw-lan-desc ol { margin: 0 0 var(--hw-space-3); padding-left: 1.4em; }
.hw-lan-desc a { overflow-wrap: anywhere; }

/* D-076, layout B: the venue map is the LAN page's hero. The frame fills the card; the title, venue, facts and
   countdown sit on a plate over its left edge that fades into the map, and the plate lets clicks through to the map
   except on its own text and links. With no venue map the plate stands alone on the page's own wash. Phones: the map
   on top, the plate under it, the credit between (it stays right after the frame, legal review L-1/Q1) */
.hw-lan-hero { position: relative; overflow: hidden; border-radius: var(--hw-radius-3); border: 1px solid var(--hw-edge);
  background: radial-gradient(900px 420px at 85% 0%, color-mix(in srgb, var(--hw-electric) 16%, transparent), transparent 70%), var(--hw-bg-1); }
.hw-lan-hero.hw-geo { min-height: 380px; display: flex; }
.hw-lan-hero .hw-lan-hero__map { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; background: var(--hw-bg-0);
  margin: 0; border-radius: 0; }   /* over the geo panel's own .hw-geo iframe rule */
.hw-lan-hero__plate { position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: flex-end;
  gap: var(--hw-space-3); padding: var(--hw-space-6); pointer-events: none; }
.hw-lan-hero__plate > * { pointer-events: auto; }
.hw-lan-hero__plate .hw-eyebrow { margin: 0; }
.hw-lan-hero__plate .hw-lan-facts { margin: var(--hw-space-2) 0 0; }
.hw-lan-hero__plate .hw-countdown { margin-top: var(--hw-space-2); }
/* the user: the venue's QR code (a maps link, lans/geo.venue_link) left of the facts, in the site's look: indigo-night
   modules on the lavender ink (17.9:1, so phones still read it), the small 45° chamfer (D-080; the cut stays inside the
   4-module quiet zone, no module is lost) and the periwinkle glow, brighter on hover. The SVG's own #fff/#000 are the
   fallback. Facts wrap beside it, 88-120 px */
.hw-lan-facts-row { display: flex; align-items: stretch; gap: var(--hw-space-4); margin-top: var(--hw-space-2); }
.hw-lan-facts-row .hw-lan-facts { margin: 0; flex: 1; align-content: center; }
.hw-lan-qr { --c: var(--hw-cut-sm); flex: none; display: block; width: clamp(88px, 18%, 120px); align-self: center; line-height: 0;
  filter: drop-shadow(0 0 1px var(--hw-edge-2)) drop-shadow(0 0 10px color-mix(in srgb, var(--hw-electric) 28%, transparent));
  transition: filter .2s; }
.hw-lan-qr:hover { filter: drop-shadow(0 0 1px var(--hw-glow)) drop-shadow(0 0 16px color-mix(in srgb, var(--hw-glow) 45%, transparent)); }
.hw-lan-qr .hw-qr { width: 100%; height: auto; clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)),
  calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
/* the user: "still plain colors": round dots in an indigo → UV-violet sweep (lightest end ≥ 5:1 on the ground), indigo
   eye rings with UV pupils, the lavender ink as the ground */
.hw-lan-qr .hw-qr__ground { fill: var(--hw-ink); }
.hw-lan-qr .hw-qr stop:first-child { stop-color: var(--hw-bg-2); }
.hw-lan-qr .hw-qr stop:last-child { stop-color: var(--seat-mine); }
.hw-lan-qr .hw-qr__eye { fill: var(--hw-bg-2); }
.hw-lan-qr .hw-qr__pupil { fill: var(--seat-mine); }
.hw-lan-qr:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: 3px; }
.hw-lan-hero.hw-geo .hw-lan-hero__plate { width: min(600px, 100%);
  background: linear-gradient(90deg, color-mix(in srgb, var(--hw-bg-0) 94%, transparent) 0%, color-mix(in srgb, var(--hw-bg-0) 86%, transparent) 62%, color-mix(in srgb, var(--hw-bg-0) 0%, transparent) 100%); }
.hw-lan-hero__venue { font: 600 var(--hw-text-xs)/1.2 var(--hw-mono); letter-spacing: var(--hw-track-caps); text-transform: uppercase; color: var(--hw-electric); }
.hw-lan-hero .hw-geo__credit { position: absolute; right: 10px; bottom: 6px; z-index: 1; margin: 0; padding: 2px 6px;
  font-size: 11px; text-shadow: 0 0 4px #000, 0 0 2px #000; }   /* the user: no background box; the shadow keeps it legible on the map */
@media (max-width: 860px) {
  .hw-lan-hero.hw-geo { display: block; min-height: 0; }
  .hw-lan-hero .hw-lan-hero__map { position: static; height: 240px; }
  .hw-lan-hero .hw-geo__credit { position: static; text-align: right; background: none; padding: 4px 12px 0; }
  .hw-lan-hero.hw-geo .hw-lan-hero__plate { width: 100%; background: none; padding: var(--hw-space-4) var(--hw-space-5) var(--hw-space-5); }
}
/* D-076: the description folds to its first lines; "Read more" opens the rest (static/hiw/lan.js); without JS all shows */
.hw-lan-desc.is-folded { max-height: 4.6em; overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent); mask-image: linear-gradient(180deg, #000 55%, transparent); }
.hw-lan-desc__more { all: unset; cursor: pointer; margin-top: var(--hw-space-2); font-size: var(--hw-text-sm); color: var(--hw-glow); }
.hw-lan-desc__more:hover { text-decoration: underline; }
.hw-lan-desc__more:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: 2px; }


/* the user: the LAN description runs the whole page width (the design system caps .hw-intro at 60ch) */
.hw-lan-desc { max-width: none; }

/* the "Event Info" heading over the description: the section takes the gap, the text sits close under its heading */
.hw-lan-info { margin-top: var(--hw-space-5); }
.hw-lan-info .hw-lan-desc { margin-top: var(--hw-space-2); }

/* a Registered row with a seat lights it on the map (lan.js): it reads as clickable */
.hw-who tr.is-seat-link { cursor: pointer; }
.hw-who tr.is-seat-link:hover > td { background: rgba(255, 255, 255, .04); }
.hw-who tr.is-seat-link:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: -2px; }
/* the user: the LAN's state ("This LAN is over…", "The LAN is on…") heads the hero, top left; the rest of the plate
   stays at the bottom (the plate is a column justified to the end; this one is pushed to the top) */
.hw-lan-hero__status { align-self: flex-start; margin: 0 0 auto; white-space: normal; max-width: 100%; line-height: 1.35;
  border-radius: var(--hw-radius-2); padding: 5px 10px; color: var(--hw-ink); background: color-mix(in srgb, var(--hw-bg-0) 55%, transparent); }
.hw-lan-hero:not(.hw-geo) .hw-lan-hero__status { margin-bottom: var(--hw-space-2); }

/* D-080, the chamfer (the user picked version A; the rule set is at the end of design/components.css): the LAN page's
   hero is cut like every panel, its 1 px edge a cut ring; legal review L-1's credit keeps clear of the bottom-right cut */
.hw-lan-hero { --c: var(--hw-cut-lg); border-radius: 0; border-color: transparent; clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
.hw-lan-hero::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; background: var(--hw-edge);
  clip-path: polygon(evenodd, var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c), var(--c) 0,
    calc(var(--c) + .42px) 1px, 1px calc(var(--c) + .42px), 1px calc(100% - 1px), calc(100% - var(--c) - .42px) calc(100% - 1px),
    calc(100% - 1px) calc(100% - var(--c) - .42px), calc(100% - 1px) 1px, calc(var(--c) + .42px) 1px); }
.hw-lan-hero .hw-geo__credit { right: calc(var(--hw-cut-lg) + 10px); border-radius: 0; }
.hw-lan-hero__status { border-radius: 0; }
.hw-lan-map3d iframe, .hw-geo iframe { border-radius: 0; }
.hw-nav__logout { --c: var(--hw-cut-sm); border-radius: 0; clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
.hw-nav__logout:focus-visible { outline-offset: -3px; }
/* the user: the LAN's number before its name in the hero ("#1 Kuusirinne"), the LANs list's "#"; quieter than the name */
.hw-lan-hero__no { color: var(--hw-ink-3); font-family: var(--hw-counter); font-weight: 600; margin-right: .15em; }
/* the user: "make Lans and Members scrolling so that headers row is visible all the time": the header row of the LANs
   list and the members list sticks under the (sticky) nav while the page scrolls. A sticky cell sticks to its nearest
   scroll container, so these two tables' wrapper stops being one (neither scrolls sideways at any width: the LANs list
   drops its games column on phones, the members table was fitted to 375 px, D-047) */
.hw-table-wrap:has(> .hw-history:not(.hw-lanhist)), .hw-table-wrap:has(> .hw-members) { overflow: visible; }
.hw-history:not(.hw-lanhist) thead th, .hw-members thead th {
  position: sticky; top: var(--hw-nav-h); z-index: 2;
  background: color-mix(in srgb, var(--hw-bg-1) 94%, transparent); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
@media (max-width: 1080px) { .hw-history:not(.hw-lanhist) thead th, .hw-members thead th { top: 56px; } }
/* … and where the LANs list is wider than the page (its games and seat-map columns, under 1100 px), the list keeps its
   own sideways scroll as before and becomes a screen-tall box that scrolls both ways, its header row stuck to the box's
   top. The members table fits every width, so it keeps the page-level header */
@media (max-width: 1100px) {
  .hw-table-wrap:has(> .hw-history:not(.hw-lanhist)) { overflow: auto; max-height: calc(100dvh - 56px - 64px - 16px); overscroll-behavior: contain;
    position: relative; }
  /* the height: the nav, the section's bottom padding and some air, so at the page's end the box top clears the nav;
     position: relative keeps the rows' screen-reader spans (.sr, absolute) inside the box, not stretching the page */
  .hw-history:not(.hw-lanhist) thead th { top: 0; }
}


/* the user: "when any counter element goes to "00" basically over, flash that element": a countdown box (lan.js) or the
   nav clock's digits (nav.js) that roll to zero flash once, in the counters' own orange */
@keyframes hw-zero-box { 0% { background-color: color-mix(in srgb, var(--hw-accent-2) 55%, transparent); filter: brightness(1.7); } 100% { background-color: color-mix(in srgb, var(--hw-accent-2) 6%, transparent); filter: none; } }
@keyframes hw-zero-digit { 0% { color: #fff; text-shadow: 0 0 10px #ff8a1f, 0 0 22px color-mix(in srgb, var(--hw-accent-2) 90%, transparent); } 100% { text-shadow: none; } }
.hw-countdown__unit.is-zero { animation: hw-zero-box .9s ease-out 1; }
.hw-clock .hw-roll__vis > span.is-zero { animation: hw-zero-digit .9s ease-out 1; }

/* D-085: the hero's venue label in the kit's label face, Roboto Condensed (as .hw-eyebrow, design/components.css) */
.hw-lan-hero__venue { font-family: var(--hw-cond); }
/* the user: "LAN events since 2002." under the logo on the landing, after the build (templates/lans/home.html,
   static/hiw/landing.js); the hero keeps logo and line together in the middle of the screen */
.hw-hero { align-content: center; row-gap: var(--hw-space-5); }
.hw-hero__tagline { margin: 0; text-align: center; font: 500 var(--hw-text-lg)/1.3 var(--hw-cond); letter-spacing: .14em;
  text-transform: uppercase; color: var(--hw-ink-2); text-shadow: 0 0 18px rgba(31, 143, 255, .45);
  transition: opacity .9s var(--hw-ease), transform .9s var(--hw-ease); }
.hw-hero__tagline.is-waiting { opacity: 0; transform: translateY(8px); }
@media (max-width: 560px) { .hw-hero__tagline { font-size: var(--hw-text-md); letter-spacing: .1em; } }

/* D-093 (the user: "Reduce these font sizes to match other elements in the page"): the member card's values (nick,
   rank, LANs, name, age, municipality, dates, computer, net connection) at the body size, as the LAN page's facts and the
   admins' list, not the 28 px stat figure; the rank's insignia scaled to that text */
.hw-profile .hw-stat__value { font-size: var(--hw-text-md); font-weight: 500; line-height: 1.35; }
.hw-profile .hw-rank--lg { gap: var(--hw-space-2); font-size: var(--hw-text-sm); }
.hw-profile .hw-rank--lg .hw-rank__icon { width: 42px; height: 24px; }

/* the user, on the profile: ""Never shown to other members" mark these a different color". The private part in the
   kit's amber (accent-2) instead of the shared fields' violet: its title, its labels and a lit left edge on a faint
   amber ground. The title's words still say it, so the colour is never the only cue. */
.hw-private { --hw-private: var(--hw-accent-2); padding: var(--hw-space-4); border-left: 3px solid var(--hw-private);
  background: color-mix(in srgb, var(--hw-private) 7%, transparent); }
.hw-private .hw-eyebrow { color: var(--hw-private); }
.hw-private :is(label, .hw-label, .hw-field__label) { color: color-mix(in srgb, var(--hw-private) 80%, var(--hw-ink)); }
.hw-private :is(input, select, textarea):focus { border-color: var(--hw-private); }

/* the user: "Less width for rank because longest one fit too loosely current space. Give more space to nick & details."
   Rank is as wide as its longest name in the page's language (insignia + 5 px + name, measured): Finnish
   "Sotilaskarkuri" 111 px, English "Second Lieutenant" 128 px; no right padding, the centred Spot column is the air
   after it. Nick and its details take what Rank gives up (Finnish +24 px, English +6 px). */
.hw-who th:nth-child(2) { width: 138px; }
html[lang="fi"] .hw-who th:nth-child(2) { width: 120px; }
.hw-who td:nth-child(2), .hw-who th:nth-child(2) button { padding-right: 0; }
/* … "Make the scroller for name & nick slower": 50 → 25 px/s in this table (static/hiw/scroller.js reads it) */
.hw-who { --hw-scroll-speed: 25; }

/* the user: "Still LAN and MEMBERS page headers are not locked + scrolling is for whole page, not the members/lan items
   list only": the LANs list and the members list scroll inside their own frame at every width, as tall as the window
   leaves under the menu and the page title; the header row is locked to the frame's top (top 0 inside it, over the
   v0.4-211 page-level rules above). The page around it stays still, and the frame scrolls sideways too where a list is
   wider than the screen. */
.hw-table-wrap:has(> .hw-history:not(.hw-lanhist)), .hw-table-wrap:has(> .hw-members) {
  overflow: auto; max-height: max(260px, calc(100dvh - var(--hw-nav-h) - 170px)); overscroll-behavior: contain;
  position: relative; scrollbar-color: var(--hw-edge-2) transparent; }
.hw-history:not(.hw-lanhist) thead th, .hw-members thead th { top: 0; }
.hw-table-wrap:has(> .hw-members) { max-height: max(260px, calc(100dvh - var(--hw-nav-h) - 216px)); }   /* room for the "N members" line under it */

/* the user: GUI kit v2 K-19.02, the "ghost + highlight" chart, on the member page (templates/members/participation.html):
   ghost bars = the club's LANs per year, the lit line = the member's, in ultraviolet (the confirmed-seat UV: a violet
   halo, the UV line, a near-white core); the kit's heading row, legend, dashed grid and mono axis */
.hw-kchart { --uv-halo: var(--seat-mine); --uv-line: var(--seat-mine-led); --uv-core: color-mix(in srgb, var(--seat-mine-led) 25%, var(--hw-ink));
  --ghost: color-mix(in srgb, var(--hw-ink-3) 18%, transparent); --ghost-edge: color-mix(in srgb, var(--hw-ink-3) 45%, transparent);
  display: grid; gap: var(--hw-space-2); }
.hw-kchart__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--hw-space-2) var(--hw-space-3); }
.hw-kchart__title { font-family: var(--hw-cond); font-weight: 700; font-size: 13px; letter-spacing: var(--hw-track-caps);
  text-transform: uppercase; color: var(--uv-line); }
.hw-kchart__tag { font-family: var(--hw-mono); font-size: 12px; color: var(--hw-ink-3); padding: 2px 8px; border: 1px solid var(--hw-edge); }
.hw-kchart__legend { display: flex; gap: var(--hw-space-4); font-family: var(--hw-cond); font-size: 12px; letter-spacing: var(--hw-track-caps);
  text-transform: uppercase; color: var(--hw-ink-2); }
.hw-kchart__key { display: inline-flex; align-items: center; gap: 8px; }
.hw-kchart__key::before { content: ""; display: inline-block; }
.hw-kchart__key--line::before { width: 22px; height: 3px; background: var(--uv-line); box-shadow: 0 0 8px var(--uv-halo); }
.hw-kchart__key--bar::before { width: 11px; height: 11px; background: var(--ghost); border-top: 1px solid var(--ghost-edge); }
.hw-kchart__svg { display: block; width: 100%; height: auto; overflow: visible; }
.hw-kchart__grid { stroke: var(--hw-edge); stroke-width: 1; stroke-dasharray: 3 4; }
.hw-kchart__tick, .hw-kchart__year { fill: var(--hw-ink-3); font-family: var(--hw-mono); font-size: 11px; }
.hw-kchart__bar { fill: var(--ghost); stroke: var(--ghost-edge); stroke-width: 1; }
.hw-kchart__bar:hover { fill: color-mix(in srgb, var(--hw-ink-3) 30%, transparent); }
.hw-kchart__halo, .hw-kchart__line, .hw-kchart__core { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.hw-kchart__halo { stroke: var(--uv-halo); stroke-width: 7; opacity: .7; }
.hw-kchart__line { stroke: var(--uv-line); stroke-width: 2.4; }
.hw-kchart__core { stroke: var(--uv-core); stroke-width: .9; }
.hw-kchart__dot { fill: var(--uv-line); stroke: var(--uv-core); stroke-width: 1.5; }
.hw-kchart__end { fill: var(--uv-core); }
.hw-kchart__peak { fill: var(--uv-line); font-family: var(--hw-mono); font-size: 11px; font-weight: 700; letter-spacing: .04em; }
@media (prefers-reduced-motion: no-preference) {
  .hw-kchart__line, .hw-kchart__core, .hw-kchart__halo, .hw-kchart__haze { stroke-dasharray: 100; stroke-dashoffset: 100; animation: hw-kchart-draw 1.2s ease-out forwards; }
}
@keyframes hw-kchart-draw { to { stroke-dashoffset: 0; } }
/* on a phone the chart scales to about half its drawn size: its labels are drawn larger so they stay about 10 px */
@media (max-width: 560px) { .hw-kchart__tick, .hw-kchart__year, .hw-kchart__peak { font-size: 19px; } }
/* the kit's effects on the member chart (static/hiw/kchart.js; GUI kit v2 kit.css read for the look): the haze under the
   halo, the hit area, the lit bar, the crosshair, the ring + waves (V-10/V-13), the Current pulse + glint + sparks (LF-3),
   and the K-27 hover card. All in the chart's ultraviolet */
.hw-kchart__haze { fill: none; stroke: var(--uv-halo); stroke-width: 18; opacity: .28; stroke-linecap: round; stroke-linejoin: round; }
.hw-kchart__svg:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: 4px; }
.hw-kchart__hit { fill: transparent; cursor: crosshair; }
.hw-kchart__bar.is-lit { fill: color-mix(in srgb, var(--uv-line) 22%, transparent); stroke: color-mix(in srgb, var(--uv-line) 60%, transparent); }
.hw-kchart__hair { opacity: 0; transition: opacity .12s; pointer-events: none; }
.hw-kchart__hair.is-on { opacity: 1; }
.hw-kchart__hair line { stroke: color-mix(in srgb, var(--hw-ink-2) 60%, transparent); stroke-width: 1; stroke-dasharray: 3 3; }
.hw-kchart__hair text { fill: var(--uv-line); font-family: var(--hw-mono); font-size: 11px; font-weight: 600; }
.hw-kchart__ring { opacity: 0; transition: opacity .12s; pointer-events: none; }
.hw-kchart__ring.is-on { opacity: 1; }
.hw-kchart__mark { fill: color-mix(in srgb, var(--uv-line) 35%, transparent); stroke: var(--uv-line); stroke-width: 1.5;
  filter: drop-shadow(0 0 4px var(--uv-halo)); }
.hw-kchart__mark-core { fill: var(--uv-core); }
.hw-kchart__wave { fill: none; stroke: var(--uv-line); stroke-width: 1.2; opacity: 0; }
.hw-kchart__ring.is-on .hw-kchart__wave { animation: hw-kchart-rip 1.8s cubic-bezier(.2, .6, .35, 1) infinite; }
.hw-kchart__ring.is-on .hw-kchart__wave:nth-child(2) { animation-delay: .6s; }
.hw-kchart__ring.is-on .hw-kchart__wave:nth-child(3) { animation-delay: 1.2s; }
@keyframes hw-kchart-rip { 0% { r: 5px; opacity: 0; stroke-width: 1.8; } 8% { opacity: .9; } 100% { r: 26px; opacity: 0; stroke-width: .4; } }
.hw-kchart__pulse { fill: none; stroke: var(--uv-core); stroke-width: 2.4; stroke-linecap: round; opacity: 0; pointer-events: none;
  filter: drop-shadow(0 0 3px var(--uv-line)); }
.hw-kchart__glint { fill: var(--uv-core); filter: drop-shadow(0 0 3px var(--uv-line)); }
.hw-kchart__spark { stroke: var(--uv-core); stroke-width: 1; stroke-linecap: round; }
.hw-kchart__sparks { pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .hw-kchart__ring.is-on .hw-kchart__wave { animation: none; }
  .hw-kchart__ring.is-on .hw-kchart__wave:first-child { opacity: .5; r: 12px; } }
/* K-27 the hover card: the kit's frame (a tinted border in the item's tone, the cond uppercase title, a grid table of
   divs, a dashed foot); a locked card keeps its place and says so with a brighter border */
.hw-ktip { position: fixed; z-index: 70; left: 0; top: 0; box-sizing: border-box; width: 296px; max-width: calc(100vw - 14px);
  padding: 9px 11px 8px; border: 1px solid color-mix(in srgb, var(--seat-mine-led) 55%, transparent);
  background: color-mix(in srgb, var(--hw-bg-1) 94%, transparent); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: 0 12px 30px color-mix(in srgb, var(--hw-bg-0) 70%, transparent), 0 0 16px color-mix(in srgb, var(--seat-mine) 25%, transparent);
  color: var(--hw-ink); font: 400 11.5px/1.4 var(--hw-sans); font-variant-numeric: tabular-nums;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  pointer-events: none; opacity: 0; transition: opacity .12s; }
.hw-ktip.is-on { opacity: 1; }
.hw-ktip.is-lock { border-color: var(--seat-mine-led); }
.hw-ktip__t { margin-bottom: 6px; font: 600 11px/1.25 var(--hw-cond); letter-spacing: .1em; text-transform: uppercase; color: var(--seat-mine-led); }
.hw-ktip__t span { color: var(--hw-ink); }
.hw-ktip__tt { display: grid; grid-template-columns: auto repeat(3, minmax(0, 1fr)); column-gap: 12px; row-gap: 3px; align-items: baseline; }
.hw-ktip__th { font: 500 10px/1.2 var(--hw-cond); letter-spacing: .06em; text-transform: uppercase; color: var(--hw-ink-3); text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-ktip__th::before { content: ""; display: block; width: 18px; margin: 0 0 3px auto; }
.hw-ktip__th--line::before { height: 0; border-top: 2px solid var(--seat-mine-led); }
.hw-ktip__th--bar::before { height: 7px; background: color-mix(in srgb, var(--hw-ink-3) 45%, transparent); }
.hw-ktip__tl { font: 400 11px/1.3 var(--hw-sans); color: var(--hw-ink-3); }
.hw-ktip__td { font: 500 13px/1.3 var(--hw-mono); color: var(--hw-ink); text-align: right; white-space: nowrap; }
.hw-ktip__foot { margin-top: 6px; padding-top: 5px; border-top: 1px dashed var(--hw-edge-2); font: 400 10.5px/1.3 var(--hw-mono); color: var(--hw-ink-3); }
/* the running totals' row: under a hairline, the span as its label, a step quieter than the year's own row */
.hw-ktip__tl.is-cum, .hw-ktip__td.is-cum { padding-top: 4px; border-top: 1px solid var(--hw-edge); }
.hw-ktip__td.is-cum { color: var(--hw-ink-2); }
.hw-ktip__td--pct { color: var(--seat-mine-led); }
.hw-ktip__td--pct.is-cum { color: color-mix(in srgb, var(--seat-mine-led) 75%, var(--hw-ink-2)); }

/* D-110: cooldown marks on the profile pages. A running one in red with its word ("Jäähyllä"), so the colour is never
   the only cue; ended and cancelled ones quiet. */
.hw-cooldown-marks { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.hw-cooldown-mark { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; padding: 6px 10px;
  border: 1px solid var(--hw-edge); }
.hw-cooldown-mark__state { font-weight: 700; color: var(--hw-ink-2); }
.hw-cooldown-mark.is-cooling { border-color: color-mix(in srgb, var(--hw-danger) 55%, transparent); }
.hw-cooldown-mark.is-cooling .hw-cooldown-mark__state { color: var(--hw-danger); }

/* D-111 (the user: "Site exit button should be same purple that we have for 3D model \"Exit text\""): the log-out tile
   in the exit's own accent (--hw-accent, the 3D map's EXIT and its floor guide); the hover fills it */
.hw-nav__logout { color: var(--hw-accent); background: color-mix(in srgb, var(--hw-accent) 20%, var(--hw-bg-2)); }
.hw-nav__logout:hover { color: var(--hw-bg-0); background: var(--hw-accent); }

/* D-111 (the user: "FI & EN buttons corners are not working properly, same problem were with \"Countdown\" box"): the
   switch is cut (D-080) but drew its outline as a border and the pressed button as an inset shadow, which the cut
   slices off at the corners. As the clock was fixed: no border, the 1 px outline a cut ring in ::after */
.hw-lang { position: relative; border-color: transparent; --hw-edge-ring: var(--hw-edge); }
.hw-lang::after { content: ""; position: absolute; inset: 0; pointer-events: none; clip-path: var(--hw-ring); background: var(--hw-edge-ring); }
.hw-lang button { position: relative; }
.hw-lang button[aria-pressed="true"] { box-shadow: none; }
.hw-lang button[aria-pressed="true"]::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  clip-path: var(--hw-ring); background: var(--hw-edge-2); }

/* D-112 (the user: the chart's popup and the profile's Save "corners are broken, just like other page elements have
   had"): both are cut (D-080) but drew their outline as a border, which the cut slices off at the corners. As the clock
   and FI / EN: no border, the outline a cut ring in ::after (the popup) or ::before (Save, while it is grey) */
.hw-ktip { border-color: transparent; --hw-ktip-edge: color-mix(in srgb, var(--seat-mine-led) 55%, transparent);
  box-shadow: none; filter: drop-shadow(0 10px 24px color-mix(in srgb, var(--hw-bg-0) 70%, transparent)); }
.hw-ktip.is-lock { border-color: transparent; --hw-ktip-edge: var(--seat-mine-led); }
.hw-ktip::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: var(--hw-ktip-edge);
  clip-path: polygon(evenodd, 8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px, 8px 0,
    8.42px 1px, 1px 8.42px, 1px calc(100% - 1px), calc(100% - 8.42px) calc(100% - 1px), calc(100% - 1px) calc(100% - 8.42px),
    calc(100% - 1px) 1px, 8.42px 1px); }
.hw-save { position: relative; border-color: transparent; box-shadow: none; }
.hw-btn.hw-save[disabled] { border-color: transparent; }
.hw-btn.hw-save[disabled]::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  clip-path: var(--hw-ring); background: var(--hw-edge-2); }

/* D-112: the profile's own history (rank changes, cooldowns) side by side from 900 px */
.hw-own-history { display: grid; gap: var(--hw-space-4); }
@media (min-width: 900px) { .hw-own-history { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; } }
.hw-rank-history { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.hw-rank-history li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }

/* D-112: the password page's requirements, ticked as they are met (static/hiw/password.js); a word and a mark, never
   the colour alone */
.hw-pw-rules { padding: var(--hw-space-3) var(--hw-space-4); border-left: 3px solid var(--hw-electric);
  background: color-mix(in srgb, var(--hw-electric) 8%, transparent); }
.hw-pw-rules ul { margin: 6px 0 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.hw-pw-rules li { position: relative; padding-left: 22px; color: var(--hw-ink-2); }
.hw-pw-rules li::before { content: "•"; position: absolute; left: 6px; color: var(--hw-ink-3); }
.hw-pw-rules li.is-ok { color: var(--hw-ink); }
.hw-pw-rules li.is-ok::before { content: "✓"; left: 2px; color: var(--hw-ok); font-weight: 700; }
.hw-pw-rules li.is-bad::before { content: "✕"; left: 2px; color: var(--hw-danger); font-weight: 700; }
.hw-pw-actions { gap: var(--hw-space-3); flex-wrap: wrap; }
.hw-pw-actions .hw-btn[disabled] { opacity: .45; cursor: not-allowed; box-shadow: none; }

/* D-113 (the user: "info bubble to top-menu after \"Admin\" to indicate how many members are waiting confirmation"):
   a small count after Admin, in the danger tone of the awaiting rows, cut like the chips; it opens the filtered list */
.hw-nav__badge { --c: 4px; display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px;
  margin-left: -4px; align-self: center; font: 700 12px/1 var(--hw-sans); font-variant-numeric: tabular-nums;
  color: #fff; background: #d1202f; text-decoration: none;            /* the solid red of Unregister: white passes 5.3:1 */
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
.hw-nav__badge:hover { filter: brightness(1.15); text-decoration: none; }
.hw-nav__badge:focus-visible { outline: 2px solid var(--hw-focus); outline-offset: 2px; }
.hw-nav__sheet .hw-nav__badge { margin: 0 0 0 8px; }

/* D-114 (the user: "Top-menu nick name button corners are missing where cut"): the nick is a ghost button, its outline
   a cut ring (::before, D-080); its current-page state set a border and a glow, which the cut slices off at the corners.
   The ring itself lights instead */
.hw-nav__me[aria-current="page"] { border-color: transparent; box-shadow: none; }
.hw-nav__me[aria-current="page"]::before { background: var(--hw-electric); }
.hw-nav__me:hover { box-shadow: none; }

/* D-122: buttons and form fields take the page's font (browsers give them their own, Arial on a Mac), so even an icon
   button or a checkbox label never falls back to it */
button, input, select, textarea { font-family: inherit; }

/* D-136 (the user: "If no events booked use some place holder text"): with no LAN to come and none on, the chip holds
   a fixed text in the label's type, at every width (the label itself hides up to 1080 px) */
.hw-clock--none { font: 600 10px/1 var(--hw-cond); letter-spacing: var(--hw-track-caps); text-transform: uppercase; color: var(--hw-ink-3); white-space: nowrap; }

/* D-080, the sixth time (the user: "active cells have the same wireframe bug that many other elements, the cut corners
   are missing highlight wiring"): four cut boxes still drew their outline as a border or an inset shadow, which the cut
   slices off at the 45° corners. Swept on every signed-out page (operative/css/cut-ring-sweep.js): */
/* 1. the fields: an input cannot carry a ::before ring, so its two cuts get their stroke from background gradients
   along the 45° edge, in the border's colour and width (--hw-in-edge, then the inset glow's --hw-in-inset when focused) */
.hw-input { --hw-in-edge: var(--hw-edge); --hw-in-inset: transparent; --hw-in-a: calc(var(--c) * .7071);
  background-image:
    linear-gradient(135deg, var(--hw-in-edge) calc(var(--hw-in-a) + 1px), var(--hw-in-inset) 0 calc(var(--hw-in-a) + 2px), transparent 0),
    linear-gradient(315deg, var(--hw-in-edge) calc(var(--hw-in-a) + 1px), var(--hw-in-inset) 0 calc(var(--hw-in-a) + 2px), transparent 0);
  background-origin: border-box; background-clip: border-box; background-repeat: no-repeat; }
.hw-input:focus { --hw-in-edge: var(--hw-glow); --hw-in-inset: var(--hw-glow); }
.hw-private .hw-input:focus { --hw-in-edge: var(--hw-private); }
/* 2. the phone menu button: the ring in ::after, as the clock */
.hw-nav__menu-btn { position: relative; border-color: transparent; }
.hw-nav__menu-btn::after { content: ""; position: absolute; inset: 0; pointer-events: none; clip-path: var(--hw-ring);
  background: var(--hw-edge-2); }
/* 3. the pressed chip (2D / 3D): its ring is already electric; the border drew a second, uncut line over it */
button.hw-chip[aria-pressed="true"] { border-color: transparent; }
/* 4. the legend's LED tiles: the lit 2 px edge as a cut ring; the selected tile stays square (its ring pulses outside) */
.hw-legend__swatch:not(.hw-legend__swatch--selected) { position: relative; box-shadow: none; }
.hw-legend__swatch:not(.hw-legend__swatch--selected)::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--lit);
  clip-path: polygon(evenodd, 4px 0, 100% 0, 100% calc(100% - 4px), calc(100% - 4px) 100%, 0 100%, 0 4px, 4px 0,
    4.83px 2px, 2px 4.83px, 2px calc(100% - 2px), calc(100% - 4.83px) calc(100% - 2px), calc(100% - 2px) calc(100% - 4.83px),
    calc(100% - 2px) 2px, 4.83px 2px); }

/* D-145 (the user: "LAN käynnissä teksti vihreällä + vihreässä napissa (nyt oranssi)"): while a LAN is on, the nav's
   chip is green, not the time accent's orange: its label and value in the palette's green (--hw-ok, D-086), on a
   green-tinted button whose cut ring (D-080, ::after) is green too */
.hw-clock.hw-clock--on { color: var(--hw-ok); background: color-mix(in srgb, var(--hw-ok) 14%, transparent);
  --hw-edge-ring: color-mix(in srgb, var(--hw-ok) 60%, transparent); }
.hw-clock.hw-clock--on .hw-clock__label { color: var(--hw-ok); }
a.hw-clock.hw-clock--on:hover { --hw-edge-ring: color-mix(in srgb, var(--hw-ok) 85%, transparent); }

/* D-163 (Q-WL6 = yes; the user: "Kaikki suosituksen mukaan."): on phones too (up to 1080 px, where components.css hides
   the chip's label) a LAN that is on says so in words beside its green clock, "LAN käynnissä" / "LAN is on". Measured
   in the in-app browser on synthetic pages: the 56-px row (wordmark 89 + gaps 20 + menu button 44 + the chip, 178 in FI,
   147 in EN) takes both from 363 px in FI and 332 px in EN. Below 375 px the chip keeps the words and drops the time of
   day (while a LAN is on its value is the clock, not a countdown), so nothing wraps and the menu button keeps its 44 px
   down to 320 px. The countdown's label ("LAN in") stays hidden on phones, as before. */
@media (max-width: 1080px) {
  .hw-clock.hw-clock--on .hw-clock__label, .hw-clock.hw-clock--on .hw-clock__value { white-space: nowrap; }
  .hw-clock.hw-clock--on .hw-clock__label { display: inline; }
}
@media (max-width: 374px) { .hw-clock.hw-clock--on .hw-clock__value { display: none; } }

/* D-182 (the user: "Muutetaan "LAN IS ON" laskuri --> Vihreä, mutta laskee alaspäin siihen hetkeen, kuin lanit on
   merkitty päättyväksi."): while a LAN is on, the green chip's value counts down to its end ("1 pv 22:59:59"), wider
   than D-163's time of day. Measured in the in-app browser on synthetic pages (the 56-px row: wordmark 89 + gaps 12 + 8
   + menu button 44 + the chip, 217.5 in FI and 178.1 in EN with one-digit days, 225.4 and 185.9 with two): FI takes
   words and countdown from 402 px (410 with two-digit days), EN from 363 (371). So in Finnish the countdown goes below
   410 px and the words stay, as D-163 drops the clock; in English D-163's step at 375 px still holds. */
@media (max-width: 409px) { html[lang="fi"] .hw-clock.hw-clock--on .hw-clock__value { display: none; } }

/* C7 (C6 anomaly 4; the user's rule "Bugit tulee korjata, ellei vielä ole korjattu."): the steps above fit the chip for
   one- and two-digit days; an end or a start 100 or more days away ("100 pv …": an organizer's typo, or a LAN published
   that far ahead) pushed the phone row past its edge (FI 410–417 px, EN 375–378) or wrapped the chip onto two lines
   (the coming LAN's at 320 px; an organizer's running chip on the desktop row at 1081–1099 px, FI, from two-digit
   days). So the chip may shrink at every width: its text stays on one line and, when the row is still short of room,
   runs into the chip's right padding (9 px on phones, 12 on the desktop row), then is cut at the chip's edge, never
   past the row. The menu button keeps its 44 px. Measured on synthetic pages at 320–1200 px, FI and EN, 1 to 7 digits
   (7 is the most a date can give): the code review notes "Batch C7 — built". */
.hw-nav__tools, .hw-nav__tools > .hw-clock { min-width: 0; }
.hw-nav__tools > .hw-clock { overflow: hidden; white-space: nowrap; }
.hw-nav__tools > .hw-nav__menu-btn { flex: none; }

/* D-184 (Q-WL16 = O2; the user: "Q.WL17: o1. QWL16: o2."), amending D-163 and D-182 on narrow phones: where the words
   and the countdown do not both fit (below 410 px in Finnish, D-182's step; below 375 px in English, D-163's), a LAN
   that is on shows its countdown instead of the words, the chip still green; from the step up, both, as before. The
   screen-reader label (the chip's aria-label, "LAN on käynnissä. Avaa LANin sivu.") is the same at every width; the
   coming LAN's chip is unchanged. Measured on synthetic pages at 320-414 px, FI and EN, 1 to 3 digits:
   the code review notes "Batch C8 — built". */
@media (max-width: 374px) {
  .hw-clock.hw-clock--on .hw-clock__value { display: inline; }
  .hw-clock.hw-clock--on .hw-clock__label { display: none; }
}
@media (max-width: 409px) {
  html[lang="fi"] .hw-clock.hw-clock--on .hw-clock__value { display: inline; }
  html[lang="fi"] .hw-clock.hw-clock--on .hw-clock__label { display: none; }
}

/* D-201 (Q1 of batch C13; the user: "O2: korjaa"), amending D-193: the nav chip's value is exactly as tall in the
   server's paint (plain text) as after nav.js's first tick, when the rolling digits' wheels replace it (the logo
   lane's hw-rolldigits.css, .hw-roll__d: line-height 1.15), for both chips: before, the paint was 1.95 px (phones) /
   2.09 px (desktop row) lower and the chip grew at the first tick; a visitor without JavaScript now sees the chip at
   the same height too. In the admin this file lands in @layer hw, and admin.css's #hw-site-nav * { all: revert-layer }
   hands the nav back to that layer, so the same line applies there (lans/tests_c15 pins it to the wheels' value). */
.hw-clock__value { line-height: 1.15; }
