/* Bulletin: the board, the sent list and the compliance grid.

   Every selector is scoped under .bulletin-main, so nothing here can reach another module's
   screen; the shared tokens (--lp-*) and the control tokens come from web/styles.css, which also
   gives this module the same ground, type and top bar as Loss Prevention and Kitchen Times.

   Colour says one thing only: whether something is waiting. A card asking for a confirmation
   carries an accent edge, a confirmed one carries none, and nothing else on the screen is
   coloured. */

/* The module shell, as every other module sets it. Both lines are load-bearing and were missing
   until 8 October: without min-width:0 the shell takes the top bar's min-content width (421px) and
   overflows a phone by 31px, which cuts the right edge off every card and puts the New post button
   past the screen; without the scroll pair the shell is clipped by .main's overflow:hidden and a
   board longer than the window cannot be reached at all. */
.bulletin-main .topbar,.bulletin-main .module-shell { min-width:0; }
.bulletin-main .module-shell { overflow-y:auto; overflow-x:hidden; min-height:0; height:100%; }

.bulletin-main .bl-page { max-width:860px; margin:0 auto; padding:26px 24px 64px; display:flex; flex-direction:column; gap:22px; }
/* The one-line offer of notifications, above the feed. It is a card and not a banner: a coloured
   strip across the top of the app reads as an alert, and this is an offer somebody may ignore
   forever. One coloured control on the row, like every other row in the platform. */
.bulletin-main .bl-nudge { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:12px; margin:0; padding:14px 16px; border:1px solid var(--lp-line); border-radius:var(--radius-surface,18px); background:var(--lp-card); }
.bulletin-main .bl-nudge[hidden] { display:none; }
.bulletin-main .bl-nudge-text { margin:0; max-width:52ch; color:var(--lp-muted); font-size:13.5px; line-height:1.5; }
.bulletin-main .bl-nudge-text strong { display:block; color:var(--lp-ink); font-weight:650; }
.bulletin-main .bl-nudge-actions { display:flex; align-items:center; gap:10px; }
.bulletin-main .bl-quiet-button { min-height:var(--control-height,44px); padding:0 14px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:transparent; color:var(--lp-muted); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
.bulletin-main .bl-quiet-button:hover { color:var(--lp-ink); border-color:color-mix(in srgb, var(--lp-ink) 28%, var(--lp-line)); }
.bulletin-main .bl-quiet-button:focus-visible,.bulletin-main .bl-nudge .bl-primary:focus-visible { outline:none; box-shadow:var(--focus-ring); }

.bulletin-main .bl-error { margin:0; padding:12px 14px; border-radius:var(--radius-control,14px); background:color-mix(in srgb, var(--lp-high) 9%, var(--lp-card)); border:1px solid color-mix(in srgb, var(--lp-high) 34%, transparent); color:var(--lp-high); font-size:13.5px; }
.bulletin-main .bl-error[hidden] { display:none; }
/* A sentence about something that worked, in the same place the error appears but in the app's own
   brown rather than its red: "Post deleted." in a red panel reads as a failure. Settled is this
   module's primary everywhere else (the compliance bars, the signed stores), never a green. */
.bulletin-main .bl-note { margin:0; padding:12px 14px; border-radius:var(--radius-control,14px); background:color-mix(in srgb, var(--lp-primary) 7%, var(--lp-card)); border:1px solid color-mix(in srgb, var(--lp-primary) 22%, transparent); color:var(--lp-ink); font-size:13.5px; }
.bulletin-main .bl-note[hidden] { display:none; }
/* Taking a post down carries no colour at rest. Drawn in the app's red it was the loudest control
   on every card of a board the author wrote -- louder than Mark done, which is the thing somebody
   is on this screen to press -- so it sits quietly beside the date and turns red under a finger or
   a focus ring, where the warning is actually useful. */
.bulletin-main .bl-remove { border-color:transparent; padding:0 10px; color:var(--lp-muted); }
.bulletin-main .bl-remove:hover,.bulletin-main .bl-remove:focus-visible { color:var(--lp-high);
  border-color:color-mix(in srgb, var(--lp-high) 34%, transparent); background:color-mix(in srgb, var(--lp-high) 7%, transparent); }
/* On the compliance screen it is the only control in its panel and the panel is about taking the
   post down, so there it says so from the start. */
.bulletin-main .bl-danger .bl-remove { color:var(--lp-high); border-color:color-mix(in srgb, var(--lp-high) 30%, var(--lp-line)); }
.bulletin-main .bl-danger { border-color:color-mix(in srgb, var(--lp-high) 22%, var(--lp-line)); }
.bulletin-main .bl-danger .bl-footnote { margin:0 0 12px; }
.bulletin-main .bl-view[hidden] { display:none; }
.bulletin-main .bl-view { display:flex; flex-direction:column; gap:18px; }

.bulletin-main .bl-head { display:flex; align-items:flex-end; justify-content:space-between; gap:16px; flex-wrap:wrap; }
/* Buttons side by side or stacked always keep a small space between them; touching, they read as
   one bar. */
.bulletin-main .bl-head-actions { display:flex; flex-wrap:wrap; gap:8px; }
.bulletin-main .bl-title h2 { margin:0; font-family:var(--lp-display); font-size:27px; font-weight:600; letter-spacing:-.015em; color:var(--lp-ink); }
.bulletin-main .bl-sub { margin:3px 0 0; font-size:13.5px; color:var(--lp-muted); }
.bulletin-main .bl-back { display:inline-flex; align-items:center; min-height:var(--control-height,44px); margin:0; padding:0 2px; border:0; background:none; color:var(--lp-muted); font:inherit; font-size:12.5px; cursor:pointer; }
.bulletin-main .bl-back:hover { color:var(--lp-ink); }

.bulletin-main .bl-primary { min-height:var(--control-height,44px); padding:0 18px; border:0; border-radius:var(--radius-control,16px); background:var(--lp-ink); color:var(--lp-card); font:inherit; font-size:14.5px; font-weight:650; cursor:pointer; }
.bulletin-main .bl-primary:hover { background:color-mix(in srgb, var(--lp-ink) 88%, var(--lp-primary)); }
.bulletin-main .bl-ghost { min-height:var(--control-height,44px); padding:0 16px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-card); color:var(--lp-ink); font:inherit; font-size:14px; cursor:pointer; }
.bulletin-main .bl-ghost:hover { background:var(--lp-soft); }
.bulletin-main .bl-primary:focus-visible,.bulletin-main .bl-ghost:focus-visible,.bulletin-main .bl-confirm:focus-visible,.bulletin-main .bl-row:focus-visible { outline:none; box-shadow:var(--focus-ring); }

/* ── the feed ─────────────────────────────────────────────────────────────────────────────── */

.bulletin-main .bl-group { display:flex; flex-direction:column; gap:12px; }
.bulletin-main .bl-group + .bl-group { margin-top:20px; }
.bulletin-main .bl-group-label { margin:0 0 2px; font-size:11px; letter-spacing:.1em; text-transform:uppercase; font-weight:700; color:var(--lp-muted); }
.bulletin-main .bl-empty { margin:0; padding:18px 2px; font-size:14px; color:var(--lp-muted); }

.bulletin-main .bl-card { border:1px solid var(--lp-line); border-radius:var(--radius-surface,18px); background:var(--lp-card); padding:17px 19px 15px; box-shadow:var(--lp-shadow); }
.bulletin-main .bl-card-open { border-left:3px solid var(--lp-accent); padding-left:17px; }
.bulletin-main .bl-card-head { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.bulletin-main .bl-meta { display:flex; align-items:center; gap:8px; min-width:0; }
.bulletin-main .bl-kind { flex:0 0 auto; font-size:10.5px; letter-spacing:.09em; text-transform:uppercase; font-weight:750; color:var(--lp-muted); }
.bulletin-main .bl-kind-action { color:var(--lp-primary); }
.bulletin-main .bl-meta-text { font-size:12.5px; color:var(--lp-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bulletin-main .bl-chip { flex:0 0 auto; padding:3px 10px; border-radius:999px; font-size:12px; font-weight:650; background:var(--lp-soft); color:var(--lp-muted); }
.bulletin-main .bl-chip-open { background:color-mix(in srgb, var(--lp-accent) 13%, var(--lp-card)); color:color-mix(in srgb, var(--lp-accent) 62%, var(--lp-ink)); }
.bulletin-main .bl-chip-done { background:var(--lp-soft); color:var(--lp-muted); }
.bulletin-main .bl-chip-quiet { background:transparent; color:var(--lp-muted); }

.bulletin-main .bl-card-title { margin:9px 0 6px; font-family:var(--lp-display); font-size:19px; font-weight:600; line-height:1.28; color:var(--lp-ink); }
.bulletin-main .bl-card-body p { margin:0 0 9px; font-size:14.5px; line-height:1.65; color:color-mix(in srgb, var(--lp-ink) 92%, var(--lp-muted)); }
.bulletin-main .bl-card-body p:last-child { margin-bottom:0; }
.bulletin-main .bl-card-foot { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:13px; padding-top:11px; border-top:1px solid var(--lp-line); }
.bulletin-main .bl-posted { font-size:12.5px; color:var(--lp-muted); }
.bulletin-main .bl-due { font-size:12.5px; color:var(--lp-muted); }
.bulletin-main .bl-due-late { color:var(--lp-high); font-weight:650; }
.bulletin-main .bl-confirm { margin-left:auto; min-height:var(--control-height,44px); padding:0 20px; border:0; border-radius:var(--radius-control,16px); background:var(--lp-primary); color:var(--lp-primary-ink); font:inherit; font-size:14.5px; font-weight:650; cursor:pointer; }
.bulletin-main .bl-confirm:hover { background:color-mix(in srgb, var(--lp-primary) 88%, var(--lp-ink)); }

/* ── sent ─────────────────────────────────────────────────────────────────────────────────── */

.bulletin-main .bl-rows { border:1px solid var(--lp-line); border-radius:var(--radius-surface,18px); background:var(--lp-card); overflow:hidden; }
.bulletin-main .bl-row { display:flex; align-items:center; gap:14px; width:100%; padding:14px 18px; border:0; border-bottom:1px solid var(--lp-line); background:none; font:inherit; text-align:left; cursor:pointer; }
.bulletin-main .bl-row:last-child { border-bottom:0; }
.bulletin-main .bl-row:hover { background:var(--lp-ground); }
.bulletin-main .bl-row-main { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
.bulletin-main .bl-row-title { font-size:14.5px; font-weight:600; color:var(--lp-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bulletin-main .bl-row-meta { font-size:12.5px; color:var(--lp-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bulletin-main .bl-row-kind { flex:0 0 auto; font-size:10.5px; letter-spacing:.09em; text-transform:uppercase; font-weight:700; color:var(--lp-muted); }
.bulletin-main .bl-row-count { flex:0 0 auto; min-width:94px; text-align:right; font-size:13px; font-weight:600; color:var(--lp-ink); font-variant-numeric:tabular-nums; }

/* ── who confirmed ────────────────────────────────────────────────────────────────────────── */

.bulletin-main .bl-compliance { display:flex; flex-direction:column; gap:20px; }
.bulletin-main .bl-panel { border:1px solid var(--lp-line); border-radius:var(--radius-surface,18px); background:var(--lp-card); padding:16px 18px 18px; }
.bulletin-main .bl-panel-label { margin:0 0 12px; font-size:11px; letter-spacing:.1em; text-transform:uppercase; font-weight:700; color:var(--lp-muted); }
/* The hairlines between stores are each cell's own ring showing through a 1px gap, rather than a
   line colour behind the grid: with five stores in a four-wide row the background technique
   paints the empty half of the last row as a solid grey block that reads as a broken cell. */
.bulletin-main .bl-stores { display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:1px; background:var(--lp-card); border:1px solid var(--lp-line); border-radius:12px; overflow:hidden; }
.bulletin-main .bl-store { display:flex; flex-direction:column; gap:3px; padding:12px 14px; background:var(--lp-card); box-shadow:0 0 0 1px var(--lp-line); }
.bulletin-main .bl-store-name { font-size:14px; font-weight:600; color:var(--lp-ink); }
.bulletin-main .bl-store-state { font-size:12.5px; color:var(--lp-muted); }
.bulletin-main .bl-store-count { font-size:12.5px; color:var(--lp-muted); font-variant-numeric:tabular-nums; }
.bulletin-main .bl-store-signed { box-shadow:inset 3px 0 0 color-mix(in srgb, var(--lp-primary) 70%, transparent); }
.bulletin-main .bl-store-read { box-shadow:inset 3px 0 0 var(--lp-medium); }
.bulletin-main .bl-store-waiting { box-shadow:inset 3px 0 0 var(--lp-high); }
.bulletin-main .bl-store-nobody { box-shadow:inset 3px 0 0 var(--lp-line); }

.bulletin-main .bl-table-wrap { overflow-x:auto; }
.bulletin-main .bl-table { width:100%; border-collapse:collapse; font-size:13.5px; }
.bulletin-main .bl-table th { padding:0 10px 9px 0; border-bottom:1px solid var(--lp-line); font-size:10.5px; letter-spacing:.09em; text-transform:uppercase; font-weight:700; color:var(--lp-muted); text-align:left; white-space:nowrap; }
.bulletin-main .bl-table td { padding:10px 10px 10px 0; border-bottom:1px solid var(--lp-line); color:var(--lp-ink); }
.bulletin-main .bl-table tr:last-child td { border-bottom:0; }
.bulletin-main .bl-table .bl-quiet { color:var(--lp-muted); }
.bulletin-main .bl-table .bl-num,.bulletin-main .bl-table th.bl-num { text-align:right; padding-right:0; font-variant-numeric:tabular-nums; white-space:nowrap; }
.bulletin-main .bl-tick { color:var(--lp-primary); font-weight:750; }
.bulletin-main .bl-wait { color:var(--lp-muted); }
.bulletin-main .bl-footnote { margin:14px 0 0; font-size:12px; line-height:1.6; color:var(--lp-muted); }

/* ── composing ────────────────────────────────────────────────────────────────────────────── */

/* A sheet stands in the middle of a laptop or a tablet with room on every side. Ben, 13 October:
   flush on the bottom edge of a laptop it "seems like its cutoff even if it isnt". A phone keeps it
   at the bottom, where the thumb is, but lifted off the edge and clear of the home indicator, so it
   never reads as running off the glass there either. */
.bulletin-main .bl-sheet { position:fixed; inset:0; z-index:60; display:flex; align-items:center; justify-content:center; padding:24px; background:color-mix(in srgb, var(--lp-ink) 38%, transparent); }
.bulletin-main .bl-sheet[hidden] { display:none; }
.bulletin-main .bl-sheet-panel { display:flex; flex-direction:column; width:100%; max-width:620px; max-height:calc(100vh - 48px); max-height:calc(100dvh - 48px); background:var(--lp-card); border-radius:20px; box-shadow:var(--lp-shadow-lifted); }
/* A question before an act (archive, take down): the app's own, not the browser's grey box. */
.bulletin-main .bl-sheet.bl-ask { z-index:70; }
.bulletin-main .bl-ask .bl-sheet-panel { max-width:440px; }
.bulletin-main .bl-ask .bl-sheet-head { border-bottom:0; padding-bottom:0; }
.bulletin-main .bl-ask .bl-sheet-body { padding-top:10px; padding-bottom:8px; }
.bulletin-main .bl-ask-text { margin:0; font-size:14.5px; line-height:1.55; color:var(--lp-ink); }
.bulletin-main .bl-ask .bl-sheet-foot { border-top:0; justify-content:flex-end; }
.bulletin-main .bl-sheet-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:18px 22px 14px; border-bottom:1px solid var(--lp-line); }
.bulletin-main .bl-sheet-head h3 { margin:0; font-family:var(--lp-display); font-size:20px; font-weight:600; color:var(--lp-ink); }
.bulletin-main .bl-close { flex:0 0 auto; width:44px; height:44px; border:0; border-radius:var(--radius-control-sm,11px); background:var(--lp-soft); color:var(--lp-ink); font-size:20px; line-height:1; cursor:pointer; }
.bulletin-main .bl-sheet-body { flex:1 1 auto; overflow-y:auto; padding:18px 22px; display:flex; flex-direction:column; gap:16px; }
.bulletin-main .bl-sheet-foot { padding:14px 22px 18px; border-top:1px solid var(--lp-line); display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.bulletin-main .bl-sheet-note { margin:0; flex:1 1 150px; font-size:12.5px; color:var(--lp-muted); }
.bulletin-main .bl-sheet-buttons { display:flex; gap:10px; }

.bulletin-main .bl-field { display:flex; flex-direction:column; gap:7px; min-width:0; }
.bulletin-main .bl-field-row { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.bulletin-main .bl-label { font-size:12.5px; font-weight:650; color:var(--lp-ink); }
.bulletin-main .bl-hint { margin:0; font-size:12.5px; line-height:1.55; color:color-mix(in srgb, var(--lp-muted) 30%, var(--lp-ink)); }
.bulletin-main .bl-input { min-height:var(--control-height,44px); padding:0 13px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-ground); color:var(--lp-ink); font:inherit; font-size:14.5px; }
.bulletin-main .bl-textarea { padding:12px 13px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-ground); color:var(--lp-ink); font:inherit; font-size:14.5px; line-height:1.6; resize:vertical; }
.bulletin-main .bl-input:focus-visible,.bulletin-main .bl-textarea:focus-visible { outline:none; border-color:color-mix(in srgb, var(--lp-primary) 40%, var(--lp-line)); box-shadow:var(--focus-ring); }
.bulletin-main .bl-picks { display:flex; flex-wrap:wrap; gap:8px; }
.bulletin-main .bl-picks-off { opacity:.45; }
.bulletin-main .bl-pick { display:inline-flex; align-items:center; gap:8px; min-height:var(--control-height,44px); padding:0 13px; border:1px solid var(--lp-line); border-radius:999px; background:var(--lp-ground); font-size:13.5px; color:var(--lp-ink); cursor:pointer; }
.bulletin-main .bl-pick:has(input:checked) { border-color:color-mix(in srgb, var(--lp-primary) 46%, var(--lp-line)); background:var(--lp-soft); font-weight:600; }
.bulletin-main .bl-pick-wide { width:100%; border-radius:var(--radius-control,16px); }
.bulletin-main .bl-pick input { width:16px; height:16px; accent-color:var(--lp-primary); }

/* ── urgency, and the board as a board ──────────────────────────────────────────────────────── */

/* Colour here means state, not identity: a category is a word, urgency is a colour, which is the
   rule the rest of the platform follows. Two levels only, so the third stays believable. */
.bulletin-main .bl-flag { display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:999px;
  font-size:12px; font-weight:700; letter-spacing:.02em; }
.bulletin-main .bl-flag::before { content:""; width:6px; height:6px; border-radius:50%; background:currentColor; }
.bulletin-main .bl-flag-urgent { background:color-mix(in srgb, var(--lp-high) 20%, var(--lp-card)); color:color-mix(in srgb, var(--lp-high) 68%, var(--lp-ink)); }
.bulletin-main .bl-flag-important { background:color-mix(in srgb, var(--lp-medium) 24%, var(--lp-card)); color:color-mix(in srgb, var(--lp-medium) 30%, var(--lp-ink)); }
/* A pinned card already carries the open card's left edge, so urgency recolours that edge rather
   than adding a second one beside it. */
.bulletin-main .bl-card-urgent { border-left:3px solid var(--lp-high); padding-left:17px; }
.bulletin-main .bl-card-important { border-left:3px solid var(--lp-medium); padding-left:17px; }
/* The pinned band sits on a tinted ground so it reads as a strip across the top of the board
   rather than as the first two cards of the same list. */
.bulletin-main .bl-group-pinned { padding:14px 14px 4px; margin:0 -14px 4px; border-radius:var(--radius-surface,18px);
  background:color-mix(in srgb, var(--lp-high) 7%, transparent); }

/* ── how soon, and what shape a document is ─────────────────────────────────────────────────── */

.bulletin-main .bl-levels { display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.bulletin-main .bl-levels-two { grid-template-columns:repeat(2,1fr); }
.bulletin-main .bl-level { position:relative; display:block; }
.bulletin-main .bl-level input { position:absolute; opacity:0; pointer-events:none; }
.bulletin-main .bl-level span { display:flex; flex-direction:column; gap:3px; min-height:var(--control-height,44px);
  padding:10px 12px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px);
  background:var(--lp-card); font-size:13.5px; font-weight:600; color:var(--lp-ink); cursor:pointer; }
.bulletin-main .bl-level small { font-size:12px; font-weight:500; color:var(--lp-muted); }
.bulletin-main .bl-level input:checked+span { border-color:color-mix(in srgb, var(--lp-primary) 55%, var(--lp-line));
  background:color-mix(in srgb, var(--lp-primary) 8%, var(--lp-card)); }
.bulletin-main .bl-level input:focus-visible+span { box-shadow:var(--focus-ring); }
.bulletin-main .bl-optional { font-weight:500; text-transform:none; letter-spacing:0; color:var(--lp-muted); }
.bulletin-main .bl-label-sub { font-size:12px; }

/* ── dropping a file on it ──────────────────────────────────────────────────────────────────── */

.bulletin-main .bl-drop { position:relative; border:1.5px dashed color-mix(in srgb, var(--lp-line) 70%, var(--lp-muted));
  border-radius:var(--radius-surface,18px); background:color-mix(in srgb, var(--lp-card) 70%, transparent);
  padding:20px 16px; text-align:center; cursor:pointer; transition:border-color .12s, background .12s; }
.bulletin-main .bl-drop:hover { border-color:color-mix(in srgb, var(--lp-primary) 45%, var(--lp-line)); }
.bulletin-main .bl-drop-over { border-color:var(--lp-primary); border-style:solid;
  background:color-mix(in srgb, var(--lp-primary) 9%, var(--lp-card)); }
.bulletin-main .bl-drop-full { padding:12px; text-align:left; border-style:solid; cursor:default; }
.bulletin-main .bl-drop-input { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
.bulletin-main .bl-drop-face { display:flex; flex-direction:column; align-items:center; gap:8px; }
.bulletin-main .bl-drop-mark { width:26px; height:26px; fill:none; stroke:var(--lp-muted); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.bulletin-main .bl-drop-text { margin:0; font-size:13.5px; font-weight:600; color:var(--lp-ink); }
.bulletin-main .bl-drop-file { display:flex; align-items:center; gap:12px; }
.bulletin-main .bl-drop-thumb { width:46px; height:46px; flex:0 0 auto; object-fit:cover; border-radius:10px; border:1px solid var(--lp-line); }
.bulletin-main .bl-drop-kind { display:flex; align-items:center; justify-content:center; width:46px; height:46px; flex:0 0 auto;
  border-radius:10px; background:color-mix(in srgb, var(--lp-primary) 12%, var(--lp-card));
  font-size:11px; font-weight:700; letter-spacing:.03em; color:color-mix(in srgb, var(--lp-primary) 70%, var(--lp-ink)); }
.bulletin-main .bl-drop-name { display:flex; flex-direction:column; gap:2px; min-width:0; text-align:left; }
.bulletin-main .bl-drop-name strong { font-size:13.5px; font-weight:600; color:var(--lp-ink); overflow-wrap:anywhere; }
.bulletin-main .bl-drop-name small { font-size:12px; color:var(--lp-muted); }
.bulletin-main .bl-drop-clear { margin-left:auto; flex:0 0 auto; width:var(--control-height,44px); height:var(--control-height,44px);
  border:0; border-radius:var(--radius-control,16px); background:transparent; font-size:20px; line-height:1;
  color:var(--lp-muted); cursor:pointer; }
.bulletin-main .bl-drop-clear:hover { background:color-mix(in srgb, var(--lp-ink) 6%, transparent); color:var(--lp-ink); }

/* ── a document kept per store ──────────────────────────────────────────────────────────────── */

.bulletin-main .bl-stores-head { display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-bottom:8px; }
.bulletin-main .bl-store-strip { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:18px; }
.bulletin-main .bl-store-chip { display:flex; flex-direction:column; gap:2px; align-items:flex-start;
  min-height:var(--control-height,44px); padding:7px 13px; border:1px solid var(--lp-line);
  border-radius:var(--radius-control,16px); background:var(--lp-card); cursor:pointer; text-align:left; }
.bulletin-main .bl-store-chip strong { font-size:13.5px; font-weight:600; color:var(--lp-ink); }
.bulletin-main .bl-store-chip small { font-size:12px; color:var(--lp-muted); }
.bulletin-main .bl-store-chip.is-on { border-color:color-mix(in srgb, var(--lp-primary) 55%, var(--lp-line));
  background:color-mix(in srgb, var(--lp-primary) 8%, var(--lp-card)); }
/* A store with no file is the store still working from paper, which is the one fact this shape
   exists to surface, so it is marked rather than left to look like the rest. */
.bulletin-main .bl-store-chip.is-missing { box-shadow:inset 3px 0 0 var(--lp-high); }
.bulletin-main .bl-store-chip:focus-visible { outline:none; box-shadow:var(--focus-ring); }

/* ── how far a post has got ─────────────────────────────────────────────────────────────────── */

.bulletin-main .bl-progress-figures { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.bulletin-main .bl-progress-number { display:block; font-size:30px; font-weight:700; line-height:1.1;
  color:var(--lp-ink); font-variant-numeric:tabular-nums; }
.bulletin-main .bl-progress-number span { font-size:19px; font-weight:600; color:var(--lp-muted); }
.bulletin-main .bl-progress-label { margin:3px 0 0; font-size:13.5px; color:var(--lp-muted); }
.bulletin-main .bl-progress-due { margin:0; font-size:12.5px; color:var(--lp-muted); white-space:nowrap; }
.bulletin-main .bl-bar { display:block; height:7px; border-radius:999px; overflow:hidden;
  background:color-mix(in srgb, var(--lp-ink) 8%, transparent); }
.bulletin-main .bl-progress .bl-bar { margin-top:14px; }
.bulletin-main .bl-bar-fill { display:block; height:100%; border-radius:999px; background:var(--lp-medium); }
.bulletin-main .bl-bar-fill.is-done { background:color-mix(in srgb, var(--lp-primary) 75%, transparent); }
.bulletin-main .bl-store-bar { display:block; margin:5px 0 2px; }
.bulletin-main .bl-table .bl-status { white-space:nowrap; }
.bulletin-main .bl-table .bl-status small { display:block; margin-top:3px; font-size:12px; }

@media (max-width:720px) {
  .bulletin-main .bl-page { padding:18px 14px 56px; }
  .bulletin-main .bl-field-row { grid-template-columns:1fr; }
  /* On a phone the chip and the meta line fight for one row, and the meta loses to the point of
     reading as three words. They get a line each instead. */
  .bulletin-main .bl-card-head { flex-wrap:wrap; }
  .bulletin-main .bl-meta { width:100%; align-items:flex-start; }
  /* "Safety and compliance · Every store" is 200px of text and a phone card gives it 155. An
     ellipsis there hides which stores the post is for, which is the one thing a manager checks, so
     it wraps instead. */
  .bulletin-main .bl-meta-text { white-space:normal; overflow:visible; }
  .bulletin-main .bl-row { align-items:flex-start; flex-wrap:wrap; }
  /* "Today, 1:40 PM · Prep and recipes · Bready Connie, Bready Eglinton" is 370px of text and a
     phone row gives it 324. Truncated, the thing it hides is which stores the post went to, which
     is the one thing somebody scanning Sent is looking for. It wraps instead, as the card's own
     meta line already does. */
  .bulletin-main .bl-row-meta { white-space:normal; overflow:visible; text-overflow:clip; }
  /* Two photos side by side on a phone are 155px each, which is not enough to judge whether the
     pesto is right -- which is the entire reason the photo is there. They stack instead. */
  .bulletin-main .bl-shots-2,.bulletin-main .bl-shots-3 { grid-template-columns:1fr; }
  .bulletin-main .bl-row-count { min-width:0; margin-left:auto; }
  .bulletin-main .bl-confirm { margin-left:0; width:100%; }
  /* A table that scrolls sideways on a phone hides the one column the screen exists for, so each
     person becomes a block: who they are, where, and the two moments with their own labels. */
  .bulletin-main .bl-table-wrap { overflow-x:visible; }
  .bulletin-main .bl-table,.bulletin-main .bl-table tbody,.bulletin-main .bl-table tr,.bulletin-main .bl-table td { display:block; width:auto; }
  .bulletin-main .bl-table thead { display:none; }
  .bulletin-main .bl-table tr { padding:11px 0; border-bottom:1px solid var(--lp-line); }
  .bulletin-main .bl-table td { padding:0; border:0; }
  .bulletin-main .bl-table td:first-child { font-weight:600; }
  .bulletin-main .bl-table td:nth-child(2),.bulletin-main .bl-table td:nth-child(3) { display:inline; font-size:12.5px; }
  .bulletin-main .bl-table td:nth-child(2)::after { content:" \00b7 "; }
  .bulletin-main .bl-table td.bl-num { display:flex; justify-content:space-between; gap:12px; margin-top:5px; text-align:left; }
  .bulletin-main .bl-table td.bl-num::before { content:attr(data-label); font-size:10.5px; letter-spacing:.09em; text-transform:uppercase; font-weight:700; color:var(--lp-muted); }
  .bulletin-main .bl-stores { grid-template-columns:1fr; }
  /* At 375px the title and the action share a row that does not fit, and the action is what gets
     cut. They wrap instead, with the button on its own line and reachable. */
  .bulletin-main .bl-head-actions { width:100%; }
  .bulletin-main .bl-head-actions > * { width:100%; }
  /* Three side-by-side urgency choices are 90px wide on a phone, which cuts every label. */
  .bulletin-main .bl-levels,.bulletin-main .bl-levels-two { grid-template-columns:1fr; }
  .bulletin-main .bl-group-pinned { margin:0 0 4px; padding:12px 12px 2px; }
  .bulletin-main .bl-store-chip { width:100%; }
  /* Two buttons side by side are 90px each on a 375px phone, which cuts "Not now". */
  .bulletin-main .bl-nudge-actions { width:100%; }
  .bulletin-main .bl-nudge-actions > * { flex:1 1 0; }
  .bulletin-main .bl-table td.bl-status { display:flex; align-items:baseline; gap:8px; margin-top:6px; white-space:normal; }
  .bulletin-main .bl-table td.bl-status small { margin-top:0; }
  .bulletin-main .bl-sheet { align-items:flex-end; padding:12px 8px max(8px, env(safe-area-inset-bottom)); }
  .bulletin-main .bl-sheet-panel { max-height:calc(100vh - 20px); max-height:calc(100dvh - 20px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  .bulletin-main .bl-sheet-buttons { width:100%; }
  .bulletin-main .bl-sheet-buttons button { flex:1 1 0; }
}

/* ── the library ──────────────────────────────────────────────────────────────────────────────

   A shelf of documents, then one document with its current file and the history of what changed.
   The only colour is the version chip, which reuses the board's two states: a document with a
   current file reads as settled, one with no file yet reads as open. */

.bulletin-main .bl-folders { display:flex; flex-wrap:wrap; gap:8px; }
.bulletin-main .bl-folder { min-height:var(--control-height,44px); padding:0 14px; border:1px solid var(--lp-line); border-radius:999px; background:var(--lp-card); color:var(--lp-muted); font:inherit; font-size:13px; cursor:pointer; }
.bulletin-main .bl-folder:hover { background:var(--lp-soft); color:var(--lp-ink); }
.bulletin-main .bl-folder.active { background:var(--lp-ink); border-color:var(--lp-ink); color:var(--lp-card); font-weight:600; }
.bulletin-main .bl-folder:focus-visible { outline:none; box-shadow:var(--focus-ring); }

.bulletin-main .bl-shelf { display:grid; gap:12px; }
/* The shelf as a grid of files, Finder- or Explorer-style: a first-page picture about three times the
   size of a desktop icon, the name under it, one quiet status line. Two across on a phone, as many
   as fit on anything wider. */
.bulletin-main .bl-shelf.bl-shelf-grid { grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); gap:22px 16px; }
/* No padding reaching past the tile: tiles keep the grid's gap between them, pointer areas included. */
.bulletin-main .bl-tile { display:flex; flex-direction:column; gap:4px; min-width:0; border-radius:10px; cursor:pointer; }
.bulletin-main .bl-tile:hover .bl-thumb { border-color:color-mix(in srgb, var(--lp-ink) 26%, var(--lp-line)); box-shadow:0 1px 2px rgba(20,17,15,.06),0 10px 22px rgba(20,17,15,.10); }
.bulletin-main .bl-tile:focus-visible { outline:none; }
.bulletin-main .bl-tile:focus-visible .bl-thumb { box-shadow:var(--focus-ring); }
.bulletin-main .bl-tile.is-archived .bl-thumb { opacity:.55; }
.bulletin-main .bl-thumb { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; width:100%; aspect-ratio:4 / 5; margin-bottom:6px; border:1px solid var(--lp-line); border-radius:10px; background:var(--lp-card); overflow:hidden; box-shadow:0 1px 2px rgba(20,17,15,.05),0 6px 16px rgba(20,17,15,.06); }
.bulletin-main .bl-thumb img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:top center; background:#fff; opacity:0; transition:opacity .2s ease; }
.bulletin-main .bl-thumb.has-image img { opacity:1; }
/* A page is shown from its top, the way a document's preview is; a photo whole, never cropped. */
.bulletin-main .bl-thumb[data-thumb-kind-of^="image/"] img { object-fit:contain; object-position:center; background:var(--lp-soft); }
.bulletin-main .bl-thumb-kind { display:inline-flex; align-items:center; justify-content:center; min-width:52px; height:52px; padding:0 8px; border-radius:12px; background:var(--lp-soft); color:var(--lp-ink); font-size:13px; font-weight:700; letter-spacing:.03em; }
.bulletin-main .bl-thumb-label { max-width:80%; font-size:12px; color:var(--lp-muted); text-align:center; }
.bulletin-main .bl-tile-title { margin:0; font-size:14.5px; font-weight:650; line-height:1.3; color:var(--lp-ink); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere; }
.bulletin-main .bl-tile-meta { font-size:12.5px; color:var(--lp-muted); }
.bulletin-main .bl-tile-open { color:color-mix(in srgb, var(--lp-accent) 62%, var(--lp-ink)); font-weight:600; }
/* The document page's file: its first page small, beside what it is. */
.bulletin-main .bl-docfile { display:grid; grid-template-columns:220px 1fr; gap:24px; align-items:start; }
.bulletin-main .bl-docfile-thumb { display:block; width:100%; padding:0; border:0; background:none; border-radius:10px; cursor:zoom-in; }
.bulletin-main div.bl-docfile-thumb { cursor:default; }
.bulletin-main .bl-docfile-thumb:focus-visible { outline:none; box-shadow:var(--focus-ring); }
.bulletin-main .bl-docfile-thumb .bl-thumb { margin:0; }
.bulletin-main .bl-docfile-info { display:flex; flex-direction:column; gap:6px; min-width:0; padding-top:4px; }
.bulletin-main .bl-docfile-name { font-size:17px; font-weight:650; color:var(--lp-ink); overflow-wrap:anywhere; }
.bulletin-main .bl-docfile-meta { font-size:13px; color:var(--lp-muted); }
.bulletin-main .bl-docfile-info .bl-change { margin-top:10px; padding-top:12px; border-top:1px solid var(--lp-line); }
.bulletin-main .bl-docfile-actions { display:flex; gap:8px; margin-top:12px; flex-wrap:wrap; }
.bulletin-main .bl-docfile-download { display:inline-flex; align-items:center; text-decoration:none; }

.bulletin-main .bl-document { display:flex; flex-direction:column; gap:18px; }
.bulletin-main .bl-document-summary { margin:0; font-size:14.5px; color:var(--lp-muted); }
/* The viewer: a bar naming the file, and the file on a quiet surface beneath it, the way a file
   opens in any other app. One surface, a hairline under the bar, no card inside the card. */
.bulletin-main .bl-doc { display:flex; flex-direction:column; border:1px solid var(--lp-line); border-radius:var(--radius-surface,18px); background:var(--lp-card); overflow:hidden; box-shadow:var(--lift,0 1px 2px rgba(20,17,15,.06)); }
.bulletin-main .bl-doc-bar { display:flex; align-items:center; gap:12px; min-height:60px; padding:10px 10px 10px 14px; border-bottom:1px solid var(--lp-line); background:var(--lp-card); }
.bulletin-main .bl-doc-icon { flex:none; display:inline-flex; align-items:center; justify-content:center; min-width:40px; height:40px; padding:0 6px; border-radius:10px; background:var(--lp-soft); color:var(--lp-ink); font-size:12px; font-weight:700; letter-spacing:.02em; }
.bulletin-main .bl-doc-icon-lg { min-width:64px; height:64px; border-radius:14px; font-size:13px; }
.bulletin-main .bl-doc-name { min-width:0; flex:1; display:flex; flex-direction:column; gap:2px; }
.bulletin-main .bl-doc-name strong { font-size:14.5px; font-weight:650; color:var(--lp-ink); overflow-wrap:anywhere; }
.bulletin-main .bl-doc-name small { font-size:12.5px; color:var(--lp-muted); font-variant-numeric:tabular-nums; }
.bulletin-main .bl-doc-tools { flex:none; display:flex; gap:8px; }
.bulletin-main .bl-icon-button { display:inline-flex; align-items:center; justify-content:center; width:44px; height:44px; border:0; border-radius:var(--radius-control-sm,11px); background:transparent; color:var(--lp-ink); cursor:pointer; text-decoration:none; }
.bulletin-main .bl-icon-button:hover { background:var(--lp-soft); }
.bulletin-main .bl-icon-button:focus-visible { outline:none; box-shadow:var(--focus-ring); }
.bulletin-main .bl-icon-button svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.bulletin-main .bl-doc-stage { display:flex; justify-content:center; align-items:flex-start; padding:20px; background:color-mix(in srgb, var(--lp-soft) 70%, var(--lp-card)); }
.bulletin-main .bl-doc-page { display:block; max-width:100%; background:#fff; border-radius:6px; box-shadow:0 1px 3px rgba(20,17,15,.10),0 8px 24px rgba(20,17,15,.08); }
.bulletin-main iframe.bl-doc-page { width:min(100%,880px); height:min(72vh,860px); border:0; }
.bulletin-main .bl-doc-pages { width:100%; display:flex; flex-direction:column; align-items:center; gap:16px; min-height:200px; }
.bulletin-main canvas.bl-doc-page { height:auto; }
.bulletin-main .bl-doc-loading { margin:auto 0; padding:40px 0; font-size:14px; color:var(--lp-muted); text-align:center; }
.bulletin-main img.bl-doc-page { max-height:78vh; object-fit:contain; }
.bulletin-main .bl-doc-file { display:flex; flex-direction:column; align-items:center; gap:10px; padding:28px 16px; text-align:center; }
.bulletin-main .bl-doc-file strong { font-size:15px; color:var(--lp-ink); overflow-wrap:anywhere; }
.bulletin-main .bl-doc-file p { margin:0 0 6px; font-size:13.5px; color:var(--lp-muted); }
.bulletin-main .bl-doc-file a { display:inline-flex; align-items:center; text-decoration:none; }
/* Full screen: the same viewer pinned over the shell, the file given every pixel below the bar. */
.bulletin-main .bl-doc.is-full { position:fixed; inset:0; z-index:200; border:0; border-radius:0; box-shadow:none; }
.bulletin-main .bl-doc.is-full .bl-doc-bar { padding-top:max(10px,env(safe-area-inset-top)); }
.bulletin-main .bl-doc.is-full .bl-doc-stage { flex:1; min-height:0; overflow:auto; padding:16px; }
/* The page's body, for the printer only: the shell goes, the sheet is all there is. Ink is dear and
   photocopies are grey, so it is dark type on white with a hairline, and a page per page. */
body[data-module="bulletin"] > .bl-print { display:none; }
@media print {
  @page { margin:10mm; }
  body[data-module="bulletin"].bl-printing > :not(.bl-print) { display:none !important; }
  body[data-module="bulletin"].bl-printing { height:auto !important; overflow:visible !important; background:#fff !important; }
  body[data-module="bulletin"].bl-printing > .bl-print { display:block !important; color:#111; font:10pt/1.4 system-ui,sans-serif; }
  body[data-module="bulletin"] .bl-print-page { break-after:page; }
  body[data-module="bulletin"] .bl-print-page:last-child { break-after:auto; }
  body[data-module="bulletin"] .bl-print-head { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; padding-bottom:6px; margin-bottom:8px; border-bottom:1px solid #bbb; }
  body[data-module="bulletin"] .bl-print-head strong { display:block; font-size:13pt; }
  body[data-module="bulletin"] .bl-print-head small { color:#444; }
  body[data-module="bulletin"] .bl-print-qr { width:22mm; height:22mm; }
  body[data-module="bulletin"] .bl-print-image { display:block; width:100%; max-height:250mm; object-fit:contain; }
}
.bulletin-main .bl-doc.is-full iframe.bl-doc-page { width:min(100%,1100px); height:100%; }
.bulletin-main .bl-doc.is-full img.bl-doc-page { max-height:100%; }
.bulletin-main .bl-change { display:flex; flex-direction:column; gap:4px; }
.bulletin-main .bl-change p { margin:0; font-size:14.5px; color:var(--lp-ink); }
.bulletin-main .bl-banner { display:flex; align-items:center; flex-wrap:wrap; gap:6px 12px; padding:12px 14px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-soft); font-size:14px; color:var(--lp-ink); }
.bulletin-main .bl-banner span { color:var(--lp-muted); flex:1; min-width:180px; }
.bulletin-main .bl-version-open { margin-left:auto; min-height:44px; padding:0 14px; font-size:13.5px; }

.bulletin-main .bl-versions { margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:10px; }
.bulletin-main .bl-version { padding:14px 16px; border:1px solid var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-card); }
.bulletin-main .bl-version.current { border-color:color-mix(in srgb, var(--lp-ink) 20%, var(--lp-line)); }
.bulletin-main .bl-version-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.bulletin-main .bl-version-head strong { font-size:14px; color:var(--lp-ink); }
.bulletin-main .bl-version p { margin:7px 0 0; font-size:13.5px; color:var(--lp-ink); }
.bulletin-main .bl-version small { display:block; margin-top:6px; }

/* A post that announces a document change. Underlined rather than coloured: colour on this screen
   means a state, and "there is a document behind this" is not a state. */
.bulletin-main .bl-doclink { display:inline-flex; align-items:center; min-height:var(--control-height,44px); margin:4px 0 0; padding:0 2px; border:0; background:none; color:var(--lp-ink); font:inherit; font-size:13.5px; font-weight:600; text-decoration:underline; text-underline-offset:3px; cursor:pointer; text-align:left; }
.bulletin-main .bl-doclink:hover { color:var(--lp-primary,var(--lp-ink)); }
.bulletin-main .bl-doclink:focus-visible { outline:none; box-shadow:var(--focus-ring); border-radius:6px; }

.bulletin-main .bl-file { min-height:var(--control-height,44px); padding:11px 12px; border:1px dashed var(--lp-line); border-radius:var(--radius-control,16px); background:var(--lp-soft); font:inherit; font-size:13.5px; color:var(--lp-ink); width:100%; box-sizing:border-box; cursor:pointer; }
.bulletin-main .bl-file:focus-visible { outline:none; border-color:color-mix(in srgb, var(--lp-primary) 40%, var(--lp-line)); box-shadow:var(--focus-ring); }

@media (max-width:720px){
  /* The preview is the screen's whole job on a phone, so it gets the height rather than the
     chrome around it, and the folder pills scroll across instead of stacking six rows deep. */
  .bulletin-main .bl-doc-stage { padding:10px; }
  .bulletin-main .bl-shelf.bl-shelf-grid { grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px 12px; }
  .bulletin-main .bl-docfile { grid-template-columns:132px 1fr; gap:16px; }
  .bulletin-main .bl-docfile-actions > * { flex:1; justify-content:center; }
  .bulletin-main iframe.bl-doc-page { height:min(64vh,560px); }
  .bulletin-main .bl-folders { flex-wrap:nowrap; overflow-x:auto; padding-bottom:4px; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
  .bulletin-main .bl-folders::-webkit-scrollbar { display:none; }
  .bulletin-main .bl-folder { flex:0 0 auto; }
}

/* ─────────────────────────────────────────────────── one store's board, in the sidebar

   Ben, 8 October 2026: somebody with more than one store wants a view of each. Drawn only when
   there is more than one, because a tab saying "Bready Connie" to the person who only has Connie
   is furniture. They sit under Board, indented, because they are views of it rather than pages
   beside it — the same posts, filtered, with each store's own outstanding count.

   Outside .bulletin-main on purpose: the module's sidebar is a sibling of its main, so these are
   the one set of selectors in this file that cannot carry the module prefix. */
body[data-module="bulletin"] #bulletin-store-nav { display:flex; flex-direction:column; gap:1px; margin:2px 0 4px 15px;
  padding-left:11px; border-left:1px solid color-mix(in srgb, var(--brown) 18%, transparent); }
body[data-module="bulletin"] #bulletin-store-nav[hidden] { display:none; }
body[data-module="bulletin"] .bl-store-tab { display:flex; align-items:center; gap:8px; width:100%; min-height:32px; padding:5px 9px;
  border:0; border-radius:8px; background:transparent; color:color-mix(in srgb, var(--ink) 66%, var(--brown));
  font:inherit; font-size:12.5px; font-weight:550; text-align:left; cursor:pointer;
  transition:background .15s ease, color .15s ease; }
body[data-module="bulletin"] .bl-store-tab:hover { background:color-mix(in srgb, var(--cream) 55%, transparent); color:var(--ink); }
body[data-module="bulletin"] .bl-store-tab.is-on { background:var(--cream); color:var(--ink); font-weight:700; }
body[data-module="bulletin"] .bl-store-tab:focus-visible { outline:none; box-shadow:var(--focus-ring); }
body[data-module="bulletin"] .bl-store-tab-name { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
body[data-module="bulletin"] .bl-store-tab-count { flex:0 0 auto; min-width:20px; padding:1px 6px; border-radius:999px;
  background:color-mix(in srgb, var(--brown) 14%, transparent); color:var(--brown);
  font-size:10.5px; font-weight:750; text-align:center; font-variant-numeric:tabular-nums; }
body[data-module="bulletin"] .bl-store-tab.is-on .bl-store-tab-count { background:var(--brown); color:var(--cream); }

/* ───────────────────────────────────────────────────────────── the composer, in sections

   Four quiet headings instead of eight labels in a column: somebody who has posted before is
   looking for the one section they want to change, and a hairline between the groups is what makes
   that scannable without turning the sheet into a stack of cards. */
.bulletin-main .bl-section { display:flex; flex-direction:column; gap:14px; padding-bottom:18px;
  border-bottom:1px solid var(--lp-line); }
.bulletin-main .bl-section:last-child { padding-bottom:2px; border-bottom:0; }
.bulletin-main .bl-section-label { margin:0; font-size:11px; font-weight:750; letter-spacing:.07em;
  text-transform:uppercase; color:var(--lp-muted); }
.bulletin-main .bl-section-label small { margin-left:8px; font-size:11.5px; font-weight:500;
  letter-spacing:0; text-transform:none; }
.bulletin-main .bl-category-name { margin-top:8px; }
.bulletin-main .bl-category-name[hidden] { display:none; }

/* ───────────────────────────────────────────────────────── photos on a post, being written */

.bulletin-main .bl-photos { display:flex; flex-direction:column; gap:10px; }
.bulletin-main .bl-photo-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:8px; }
.bulletin-main .bl-photo-grid[hidden] { display:none; }
.bulletin-main .bl-photo { position:relative; margin:0; aspect-ratio:1; border-radius:12px; overflow:hidden;
  border:1px solid var(--lp-line); background:var(--lp-soft); }
.bulletin-main .bl-photo img { width:100%; height:100%; object-fit:cover; display:block; }
.bulletin-main .bl-photo.is-pending img { opacity:.45; }
/* A finger's target, like every other control: 44px, which is why the tiles are 118px rather than
   the 96px that made the cross look right and press wrong. */
.bulletin-main .bl-photo-remove { position:absolute; top:4px; right:4px; width:44px; height:44px; padding:0;
  border:0; border-radius:999px; background:color-mix(in srgb, var(--lp-ink) 78%, transparent);
  color:#fff; font-size:18px; line-height:1; cursor:pointer; }
.bulletin-main .bl-photo-remove:hover { background:var(--lp-ink); }
.bulletin-main .bl-photo-remove:focus-visible { outline:none; box-shadow:var(--focus-ring); }
.bulletin-main .bl-photo-busy { position:absolute; inset:0; margin:auto; width:20px; height:20px;
  border-radius:999px; border:2px solid color-mix(in srgb, var(--lp-ink) 22%, transparent);
  border-top-color:var(--lp-primary); animation:bl-spin .8s linear infinite; }
@keyframes bl-spin { to { transform:rotate(360deg); } }
.bulletin-main .bl-drop-photos { padding:16px 14px; }
.bulletin-main .bl-drop-photos[hidden] { display:none; }
.bulletin-main .bl-photo-note { margin:0; font-size:12.5px; color:var(--lp-medium); }
.bulletin-main .bl-photo-note[hidden] { display:none; }

/* ─────────────────────────────────────────────────────────── photos on a post, being read

   A tile that opens the photo over the board. It was a plain link to the picture's own address,
   which on a phone with the app added to the home screen is a window with no address bar and no
   back button: the photo filled the screen and stayed there. One photo runs the width of the card
   because that is usually the point of it; two or more share the row. */
.bulletin-main .bl-shots { display:grid; gap:8px; margin:14px 0 0; }
.bulletin-main .bl-shots-2 { grid-template-columns:1fr 1fr; }
.bulletin-main .bl-shots-3 { grid-template-columns:repeat(3,1fr); }
.bulletin-main .bl-shot { display:block; border-radius:14px; overflow:hidden; border:1px solid var(--lp-line);
  background:var(--lp-soft); max-height:340px; }
/* One photo keeps its own shape, which is usually the point of it. Two or three share a row and
   are cropped to a common rectangle so the row is a row; 4:3 rather than a square, because a photo
   taken across a bench loses a third of itself to a square and the third it loses is the dish. */
.bulletin-main .bl-shots-1 .bl-shot { aspect-ratio:auto; }
.bulletin-main .bl-shots-2 .bl-shot,.bulletin-main .bl-shots-3 .bl-shot { aspect-ratio:4/3 !important; }
.bulletin-main .bl-shot img { width:100%; height:100%; object-fit:cover; display:block; }
.bulletin-main .bl-shot:focus-visible { outline:none; box-shadow:var(--focus-ring); }
.bulletin-main .bl-shot { cursor:zoom-in; }

/* The photo, full size, with a way out of it.
   Fixed to the viewport rather than scoped inside the board, because this one sits over everything;
   it is still under .bulletin-main so it cannot restyle another module. The picture keeps pinch and
   double-tap zoom (`touch-action`), which is what the old plain link was right about, and Close is
   a 44px target in the corner a thumb reaches, over a scrim so it is legible on a pale photo. */
.bulletin-main .bl-viewer { position:fixed; inset:0; z-index:200; display:flex; align-items:center;
  justify-content:center; padding:16px; background:rgba(24,19,16,.95); }
.bulletin-main .bl-viewer[hidden] { display:none; }
.bulletin-main .bl-viewer img { max-width:100%; max-height:100%; border-radius:12px; display:block;
  touch-action:pinch-zoom; }
.bulletin-main .bl-viewer-close { position:absolute; top:max(14px,env(safe-area-inset-top)); right:14px;
  width:44px; height:44px; border:0; border-radius:50%; cursor:pointer; font-size:24px; line-height:1;
  background:color-mix(in srgb, var(--lp-card) 88%, transparent); color:var(--lp-ink);
  box-shadow:var(--lp-shadow-lifted); }
.bulletin-main .bl-viewer-close:focus-visible { outline:none; box-shadow:var(--focus-ring); }
