/* ============================================================
   THE BEACON — notification mark, sitewide.
   Red Warden Studios · v1 · 2026-08-12

   THE NAME AND THE MARK
   The Beacon is the signal fire on the watchtower: lit when something has
   happened and you should come and look. It sits beside the Account link and
   is deliberately NOT a shield — the shield already means "save / follow", and
   reusing that silhouette for "there is news" would collapse two different
   ideas into one glyph. Andrew, 2026-08-12: "not a shield because that's
   already in use lol."

   Three marks already exist on this site and a fourth is being added. They
   must not be confused:
     nav logo (logo-icon.svg)      = shield + warden figure
     round table (emblems/web/cdr) = crenellated shield, painterly
     .nav-account-mark             = smooth shield, flat, UI only
     THIS                          = flame, flat, UI only

   WHY A CSS MASK RATHER THAN AN <svg>
   Same reason shield.css gives: one span per page instead of a path repeated
   across 22 pages x 2 navs, and `background: currentColor` inherits whatever
   colour the surrounding nav already uses, including :hover and .active, on
   pages whose nav CSS we do not otherwise touch. If mask-image is unsupported
   the span renders nothing and the button still has its accessible name.
   ============================================================ */

/* ---------- the control ---------- */

.rw-beacon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px is the tap target the Shield already standardised on. Below that,
     a control next to another control becomes a coin toss on a phone. */
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;

  /* 🚨 THE FLAME WAS SIZED BY A BROWSER DEFAULT NOBODY CHOSE, FOR THREE DAYS.
     Andrew, 2026-08-15: "can we make the beacon image bigger its painfully too
     small." He is right, and the cause is a latent bug rather than a taste call.
     The mark was `0.95em / 1.2em`, and `.rw-beacon` is a **<button>** — buttons
     do NOT inherit font-size, so `em` here resolved against the UA default,
     which is 13.333px in Chrome. The flame painted at 12.7x16 and nothing in
     this file said so; the size came from the user agent stylesheet.
     Both dimensions are now driven from one token below. */
  --beacon-mark: 1.75rem;   /* 28px — the flame's HEIGHT */
  font-size: 1rem;          /* pin it so no `em` here depends on the UA again */
}

.rw-beacon__mark {
  display: block;
  /* ⚠️ The width is derived, not chosen. The mask art is `viewBox='0 0 24 28'`
     and `mask-size: contain` letterboxes inside the box — so a box whose ratio
     does not match 24/28 wastes space and paints a SMALLER flame than its own
     numbers suggest. The old 0.95/1.2 box was ratio .79 against art at .857,
     which is why the flame measured 12.7x16 but only *drew* 12.7x14.8.
     Change --beacon-mark; never set these two independently. */
  width: calc(var(--beacon-mark) * 24 / 28);
  height: var(--beacon-mark);
  background: currentColor;
  opacity: 0.72;
  transition: opacity 0.18s ease, color 0.18s ease;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain;   mask-size: contain;
}

/* Unlit — outline only. A flame with a curl at the base rather than a plain
   teardrop, because a symmetrical teardrop reads as a WATER DROP at 16px and
   the whole point of the mark is that it says fire. */
.rw-beacon__mark {
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 28'><path d='M12 2 C12 2 4.8 9.4 4.8 16.2 A7.2 7.2 0 0 0 19.2 16.2 C19.2 12.7 16.4 10.2 15 7.8 C14.7 10.3 13.5 11.3 12.5 12.1 C13 8.2 12.8 5 12 2 Z' fill='none' stroke='%23000' stroke-width='2.2' stroke-linejoin='round' stroke-linecap='round'/></svg>");
          mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 28'><path d='M12 2 C12 2 4.8 9.4 4.8 16.2 A7.2 7.2 0 0 0 19.2 16.2 C19.2 12.7 16.4 10.2 15 7.8 C14.7 10.3 13.5 11.3 12.5 12.1 C13 8.2 12.8 5 12 2 Z' fill='none' stroke='%23000' stroke-width='2.2' stroke-linejoin='round' stroke-linecap='round'/></svg>");
}

.rw-beacon:hover .rw-beacon__mark,
.rw-beacon:focus-visible .rw-beacon__mark {
  opacity: 1;
}

.rw-beacon:focus-visible {
  outline: 2px solid var(--rws-crimson, #C0392B);
  outline-offset: 2px;
}

/* ---------- lit ----------
   Filled, crimson, with a soft halo. Exactly the grammar the Shield uses for
   its own outline→filled state change, so it needs no explaining to anyone who
   has already used the site once. */
.rw-beacon.is-lit .rw-beacon__mark {
  color: var(--rws-crimson, #C0392B);
  opacity: 1;
  filter: drop-shadow(0 0 5px rgba(192, 57, 43, 0.65));
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 28'><path d='M12 2 C12 2 4.8 9.4 4.8 16.2 A7.2 7.2 0 0 0 19.2 16.2 C19.2 12.7 16.4 10.2 15 7.8 C14.7 10.3 13.5 11.3 12.5 12.1 C13 8.2 12.8 5 12 2 Z' fill='%23000'/></svg>");
          mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 28'><path d='M12 2 C12 2 4.8 9.4 4.8 16.2 A7.2 7.2 0 0 0 19.2 16.2 C19.2 12.7 16.4 10.2 15 7.8 C14.7 10.3 13.5 11.3 12.5 12.1 C13 8.2 12.8 5 12 2 Z' fill='%23000'/></svg>");
}

/* The count. Absolutely positioned so lighting the beacon CANNOT change the
   width of the control — the nav must not reflow when the answer arrives a
   moment after first paint. Same discipline as .nav-account. */
.rw-beacon__count {
  position: absolute;
  top: 4px;
  right: 2px;
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--rws-crimson, #C0392B);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* ---------- the header mark (mobile) ----------
   Sits in the header bar beside the hamburger, so a lit Beacon is visible
   WITHOUT opening the menu. See the comment above mount() in js/rws-beacon.js
   for why this exists.

   `margin-left: auto` is what pushes this and the hamburger to the right edge.
   The toggle carries `margin-left: auto` of its own in all three stylesheets;
   once this element has absorbed the free space there is none left for the
   toggle's own auto margin to claim, so the two sit together with just the gap
   below between them. Nothing in the other stylesheets needs changing.

   ⚠️ Visibility is toggled from JS via the `hidden` attribute, by reading the
   hamburger's computed display — NOT by a media query here. This site has
   three different mobile breakpoints (640 / 860 / inline) and any number
   written here would be wrong on at least one of them. */
.rw-beacon--header {
  margin-left: auto;
  /* Near-zero on purpose: the spacing here is NOT set by this margin. It comes
     from `.nav-inner { gap: 2rem }` in the parent stylesheet, and that flex gap
     already separates the mark from the hamburger correctly. This margin only
     exists so as not to add to it.

     ⚠️ I nearly "fixed" this from measurements alone. The computed box gap is
     34px and the mark-to-hamburger distance computes to 48px, which sounds far
     too wide — but the flame paints at 16x20 inside a 44px touch target and the
     unread badge sits up and to the right, so on screen the two controls read
     as an obvious pair. THE NUMBERS LIED AND THE SCREENSHOT DID NOT. Look at it
     before changing it. */
  margin-right: .15rem;
  flex-shrink: 0;
}
.rw-beacon--header[hidden] { display: none; }

/* ---------- the panel ---------- */
/* Appended to <body>, not to the nav. There are TWO navs on every page
   (desktop and mobile) and putting a panel inside each would mean two copies
   of the same list, two scroll positions, and two chances to mark something
   read twice. One panel, anchored to whichever mark was pressed. */

.rw-beacon-panel {
  position: fixed;
  z-index: 900;
  width: min(370px, calc(100vw - 24px));
  max-height: min(70vh, 560px);
  overflow-y: auto;
  background: #0b0b0d;
  border: 1px solid rgba(245, 245, 245, 0.14);
  border-radius: 6px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.6);
  font-family: 'Inter', system-ui, -apple-system, Helvetica, Arial, sans-serif;
  color: #F5F5F5;
  -webkit-overflow-scrolling: touch;
}

.rw-beacon-panel[hidden] { display: none; }

/* ---------- mobile: a top sheet, not an anchored dropdown ----------
   Added 2026-08-14 with the scroll-lock fix (see the comment above open() in
   js/rws-beacon.js).

   Below the nav breakpoint the beacon mark lives inside the hamburger sheet,
   which the beacon now closes as it opens — so there is no visible element
   left to anchor to. Pinning the panel under the header instead is both the
   only correct layout and the better one: full width, one overlay, and the
   list gets the whole screen rather than a 370px column on a 390px phone.

   ⚠️ place() adds this class and CLEARS its inline top/left. If you ever make
   place() write inline styles at this width again, they will beat these rules
   and the panel will jump to the corner. */
.rw-beacon-panel--sheet {
  top: calc(var(--nav-h, 72px) + 8px);
  left: 8px;
  right: 8px;
  width: auto;
  max-height: calc(100vh - var(--nav-h, 72px) - 24px);
  max-height: calc(100dvh - var(--nav-h, 72px) - 24px);
}

.rw-beacon-panel__head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.9rem 1rem 0.7rem;
  border-bottom: 1px solid rgba(245, 245, 245, 0.1);
}

.rw-beacon-panel__head h2 {
  margin: 0;
  flex: 1;
  font-family: 'Cinzel', Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.rw-beacon-panel__clear {
  background: none;
  border: 0;
  padding: 0.2rem 0;
  /* 0.72rem is the type floor for this site. Do not go below it. */
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(245, 245, 245, 0.48);
  cursor: pointer;
  font-family: inherit;
}
.rw-beacon-panel__clear:hover { color: #F5F5F5; }

.rw-beacon-item {
  display: block;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid rgba(245, 245, 245, 0.07);
  text-decoration: none;
  color: inherit;
  /* The accent bar is how you tell at a glance WHICH division is talking to
     you. Colour is set per-division from the JS. */
  border-left: 2px solid transparent;
}
.rw-beacon-item:last-child { border-bottom: 0; }
.rw-beacon-item:hover { background: rgba(245, 245, 245, 0.04); }

.rw-beacon-item.is-unread { border-left-color: var(--rws-crimson, #C0392B); }

.rw-beacon-item__sub {
  font-size: 0.72rem; /* project type floor — was 0.68rem, below the minimum (fixed 2026-08-14) */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(245, 245, 245, 0.42);
  margin: 0 0 0.28rem;
}

.rw-beacon-item__title {
  margin: 0 0 0.2rem;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.4;
}

.rw-beacon-item__body {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.5;
  color: rgba(245, 245, 245, 0.62);
}

.rw-beacon-item__when {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.72rem;
  color: rgba(245, 245, 245, 0.42);
}

.rw-beacon-panel__empty {
  padding: 2rem 1.2rem;
  text-align: center;
  font-size: 0.85rem;
  line-height: 1.6;
  color: rgba(245, 245, 245, 0.48);
}

/* ---------- phones ----------
   CLAUDE.md hard rule: every new thing gets a dedicated pass at ~390px. Below
   560 the dropdown stops pretending to be a dropdown and becomes a sheet
   pinned under the header — a 370px floating card on a 390px screen is a
   fiddly 10px gutter on both sides and it clips against the viewport edge the
   moment the mark is near it. */
@media (max-width: 560px) {
  .rw-beacon-panel {
    left: 8px !important;
    right: 8px;
    width: auto;
    max-height: 68vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rw-beacon__mark { transition: none; }
}
