/* ==========================================================================
   Bylaws — a stack of paper. Plain black Comic Sans on a light page, blue
   links, and nothing else competing with the text.
   Layers on top of site.css: the footer and tokens stay, the space backdrop
   does not.
   ========================================================================== */

:root {
  --page:  #f6f1e2;   /* the sheet the text sits on */
  --edge:  #b9ab86;   /* its border, and every rule inside it */
  --link:  #0b39c8;   /* the blue every cross-reference is drawn in */
  --faint: #6a6151;
}

/* --------------------------------------------------------------- backdrop */
/* site.css hangs its starfields off <html>, which no body class can reach, so
   the theme is matched on the ancestor with :has(): html::before becomes the
   paper tile, html::after (the drifting second field) is dropped, and
   body::before turns into a soft vignette so the tile does not read flat. */
html:has(.theme-paper) { background: #ded4bb; }

html:has(.theme-paper)::before {
  inset: 0;
  background: url("/img/bylaws/bg-paper.png") repeat 0 0 / 150px 150px;
  animation: none;
}
html:has(.theme-paper)::after { content: none; }

.theme-paper::before {
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(70, 56, 30, .30));
}

.theme-paper {
  color: #000;
  font-family: var(--hand);
}

/* ------------------------------------------------------------------ sheet */
.bylaws {
  position: relative;
  z-index: 2;
  max-width: 860px;
  margin: 0 auto;
  padding: 84px clamp(12px, 4vw, 26px) 10px;
}

.bylaws__title {
  margin: 0 0 14px;
  font: 400 clamp(30px, 6vw, 44px)/1.1 var(--hand);
  text-align: center;
  color: #000;
  text-shadow: 2px 2px 0 rgba(255, 255, 255, .8);
}

.bylaws__body {
  padding: clamp(14px, 3vw, 30px);
  border: 3px solid var(--edge);
  background: var(--page);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .38);
}

.bylaws__body,
.bylaws__body p,
.bylaws__body li,
.bylaws__body td,
.bylaws__body th {
  font-family: var(--hand);
  color: #000;
}

.bylaws__body p { margin: 0 0 .8em; line-height: 1.6; }
.bylaws__body ul { margin: 0 0 .9em; padding-left: 1.5em; }
.bylaws__body li { margin-bottom: .25em; line-height: 1.55; }

/* ------------------------------------------------------------------ nodes */
/* One div per article, section and subsection — the unit the amendment flow
   will highlight and post against, so each keeps its own box even though the
   look is plain. Everything below an article steps in 30px from its parent. */
.node--section,
.node--subsection { margin-left: 30px; }

.node--article { margin-bottom: 1.8em; }
.node--section { margin-bottom: 1.2em; }
.node--subsection { margin-bottom: .6em; }

.node__head {
  margin: 0 0 .5em;
  font-family: var(--hand);
  font-weight: 700;
  color: #000;
}
.node--article > .node__head {
  margin-top: .4em;
  padding-bottom: .3em;
  border-bottom: 2px solid var(--edge);
  font-size: clamp(20px, 3.4vw, 26px);
  text-align: center;
}
.node--section > .node__head { font-size: 19px; }
.node--subsection > .node__head { font-size: 16px; }

/* The computed notation — Article IV, § 2, (a) — never authored, always
   derived from position by bylaws.py. */
.marker { font-weight: 700; }

/* ------------------------------------------------------- heading links */
/* Every heading ends in a chain link that copies a direct URL to that node.
   It sits faint until the heading is hovered so the page still reads as a
   printed document; on touch there is no hover, so it stays legible there. */
.node__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: .35em;
  padding: 2px;
  color: var(--link);
  opacity: .35;
  vertical-align: baseline;
  text-decoration: none;
  transition: opacity .12s ease, color .12s ease;
}
.node__head:hover .node__link,
.node__link:focus-visible { opacity: 1; }
.node__link:hover { color: var(--magenta); opacity: 1; }

.node__link-icon {
  width: .85em;
  height: .85em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
}

/* The flash after a copy: a small note pinned beside the link it came from. */
.node__link.is-copied::after {
  content: "link copied";
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
  margin-left: .5em;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--link);
  color: #fff;
  font-family: var(--hand);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

/* In propose mode a heading link would be one more thing to mis-tap while
   picking a section, and its click is swallowed by the picker anyway. */
.is-proposing .node__link { display: none; }

.node__empty { color: var(--faint); font-style: italic; }

/* ------------------------------------------------------------ references */
.ref { color: var(--link); text-decoration: underline; }
.ref:hover { color: var(--magenta); }
.ref--missing { color: #a01010; text-decoration: none; }

/* A jumped-to node should land clear of the corner button. */
.node:target { scroll-margin-top: 80px; }

/* --------------------------------------------------------------- tables */
.grid {
  margin: 0 0 1em;
  border-collapse: collapse;
  width: 100%;
  font-size: 14px;
}
.grid th,
.grid td {
  padding: 4px 8px;
  border: 1px solid var(--edge);
  text-align: left;
}
.grid th { background: rgba(0, 0, 0, .07); font-weight: 700; }
.grid caption {
  padding-bottom: 4px;
  font-size: 13px;
  text-align: left;
  color: var(--faint);
}
.grid--scoring td.val { width: 5.5em; text-align: right; font-weight: 700; }
.grid .note { color: var(--faint); font-size: 13px; }

/* ------------------------------------------------------- table of contents */
.toc {
  margin: 0 0 20px;
  border: 3px solid var(--edge);
  background: var(--page);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .3);
}

.toc__head {
  padding: 9px 14px;
  cursor: pointer;
  font: 700 18px/1.2 var(--hand);
  color: #000;
  list-style: none;               /* the ▸/▾ below replaces the native marker */
}
.toc__head::-webkit-details-marker { display: none; }
.toc__head::before { content: "\25B8  "; }
.toc[open] .toc__head::before { content: "\25BE  "; }
.toc[open] .toc__head { border-bottom: 2px solid var(--edge); }
.toc__head:hover { color: var(--link); }

.toc__list { margin: 0; padding: 10px 14px 14px 26px; list-style: none; }
.toc__list ul { margin: .2em 0 0; padding-left: 30px; list-style: none; }
.toc__article { margin-bottom: .7em; }
.toc__list a {
  color: var(--link);
  font-family: var(--hand);
  text-decoration: none;
}
.toc__list a:hover { text-decoration: underline; color: var(--magenta); }
.toc__art-link { font-weight: 700; }

/* ----------------------------------------------------------------- buttons */
.paper-btn {
  display: inline-block;
  padding: 6px 15px;
  border: 3px solid #000;
  background: var(--page);
  font: 700 15px/1.2 var(--hand);
  color: #000;
  text-decoration: none;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .55);
}
.paper-btn:hover,
.paper-btn:focus-visible {
  background: #fff;
  color: var(--link);
}

/* Pinned to the top-left of the viewport: it rides along as the page scrolls,
   so the way back out is always one tap away. Fixed rather than absolute puts
   it at the same coordinates it had at scroll 0, and keeps it there. */
.paper-btn--corner {
  position: fixed;
  z-index: 4;
  top: 24px;
  left: 24px;
}

/* ------------------------------------------------------------------ stamp */
/* Spiked oval, cut with one polygon. The border is a second copy of the same
   shape underneath: clip-path takes the border off with everything else
   outside the path, so the black edge has to be a slightly larger clipped box
   showing through the padding. The wrapper stays black through every flash,
   which is why only the face is animated. Pinned opposite .paper-btn--corner
   and at the same top, so the two sit on one line above the title. */
.stamp {
  --spikes: polygon(
    50.0% 0.0%, 55.8% 14.4%, 64.1% 2.0%, 67.0% 17.3%, 77.0% 7.9%, 76.8% 22.8%,
    87.8% 17.3%, 84.5% 30.5%, 95.5% 29.2%, 89.3% 39.9%, 99.5% 42.9%, 91.0% 50.0%,
    99.5% 57.1%, 89.3% 60.1%, 95.5% 70.8%, 84.5% 69.5%, 87.8% 82.7%, 76.8% 77.2%,
    77.0% 92.1%, 67.0% 82.7%, 64.1% 98.0%, 55.8% 85.6%, 50.0% 100.0%, 44.2% 85.6%,
    35.9% 98.0%, 33.0% 82.7%, 23.0% 92.1%, 23.2% 77.2%, 12.2% 82.7%, 15.5% 69.5%,
    4.5% 70.8%, 10.7% 60.1%, 0.5% 57.1%, 9.0% 50.0%, 0.5% 42.9%, 10.7% 39.9%,
    4.5% 29.2%, 15.5% 30.5%, 12.2% 17.3%, 23.2% 22.8%, 23.0% 7.9%, 33.0% 17.3%,
    35.9% 2.0%, 44.2% 14.4%
  );
  position: absolute;
  z-index: 4;
  top: 24px;
  right: 24px;
  padding: 3px;
  background: #000;
  clip-path: var(--spikes);
  transform: rotate(15deg);
  pointer-events: none;
}

.stamp__face {
  display: block;
  padding: 17px 28px;
  clip-path: var(--spikes);
  font: 700 15px/1 var(--hand);
  letter-spacing: 2px;
  text-align: center;
  animation: stamp-flash 1.35s steps(1, end) infinite;
}

/* Three states, black-bordered throughout, held a third of the cycle each. */
@keyframes stamp-flash {
  0%,   33.32% { background: #ffd93d; color: #d40000; }
  33.33%, 66.65% { background: #1442d8; color: #ffd93d; }
  66.66%, 100%   { background: #fff;    color: #000;    }
}

@media (prefers-reduced-motion: reduce) {
  .stamp__face { animation: none; background: #ffd93d; color: #d40000; }
}

.bylaws__back { margin: 24px 0 6px; text-align: center; }

/* --------------------------------------------------------- propose dock */
.propose {
  position: fixed;
  z-index: 20;
  right: 22px;
  bottom: 22px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  max-width: min(340px, calc(100vw - 32px));
}

.propose__toggle {
  padding: 12px 18px;
  border: 3px solid #000;
  background: #ffd93d;
  font: 700 15px/1.15 var(--hand);
  letter-spacing: .04em;
  color: #000;
  cursor: pointer;
  box-shadow: 4px 4px 0 rgba(0, 0, 0, .6);
}
.propose__toggle:hover { background: #ffe985; }
.propose__toggle:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 rgba(0, 0, 0, .6); }
.propose__toggle.is-cancel { background: #e8503c; color: #fff; }
.propose__toggle.is-cancel:hover { background: #f4705e; }

.propose__actions {
  padding: 10px;
  border: 3px solid #000;
  background: var(--page);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, .6);
}
.propose__target {
  margin: 0 0 8px;
  font: 700 13px/1.2 var(--hand);
  text-align: center;
  color: #000;
}
.propose__act {
  display: block;
  width: 100%;
  margin-bottom: 6px;
  padding: 9px 12px;
  border: 3px solid #000;
  background: #fff;
  font: 700 13px/1.15 var(--hand);
  color: #000;
  cursor: pointer;
}
.propose__act:last-child { margin-bottom: 0; }
.propose__act:hover { background: #d8ecff; color: var(--link); }

/* Striking a section out is the one destructive pick, so it is the one in
   red — the button is otherwise identical to its neighbours. */
.propose__act--delete { color: #c02a16; }
.propose__act--delete:hover { background: #ffe0da; color: #a41f0e; }

/* ------------------------------------------------------- propose mode */
/* The page becomes a picker: text stops being selectable so a drag reads as a
   pick, and every section/subsection div lights up under the pointer. */
.is-proposing .bylaws__body {
  user-select: none;
  cursor: crosshair;
}
.is-proposing .ref { cursor: crosshair; }

/* Tinted by depth, so a nested pick is visibly a different thing from the
   section around it. data-level comes off the renderer: sections are 1. */
.is-proposing .node.is-hovered {
  outline: 2px dashed rgba(0, 0, 0, .45);
  outline-offset: 3px;
  background: rgba(255, 217, 61, .40);
}
.is-proposing .node[data-level="2"].is-hovered { background: rgba(88, 170, 255, .32); }
.is-proposing .node[data-level="3"].is-hovered { background: rgba(120, 214, 130, .34); }
.is-proposing .node[data-level="4"].is-hovered { background: rgba(214, 140, 255, .32); }
.is-proposing .node[data-level="5"].is-hovered { background: rgba(255, 150, 190, .32); }

/* The pick itself: same hue, deeper, with a solid frame around it. */
.is-proposing .node.is-picked {
  outline: 3px solid #000;
  outline-offset: 3px;
  background: rgba(255, 200, 0, .72);
  box-shadow: 0 0 0 6px rgba(0, 0, 0, .12);
}
.is-proposing .node[data-level="2"].is-picked { background: rgba(60, 150, 255, .60); }
.is-proposing .node[data-level="3"].is-picked { background: rgba(90, 205, 105, .62); }
.is-proposing .node[data-level="4"].is-picked { background: rgba(196, 110, 255, .58); }
.is-proposing .node[data-level="5"].is-picked { background: rgba(255, 120, 172, .58); }

/* A pick nested inside another highlight would otherwise stack two tints. */
.is-proposing .node.is-picked .node,
.is-proposing .node.is-hovered .node { background: transparent; }

/* ------------------------------------------------------------- the footer */
/* Same chrome as the other pages, re-inked for a light background. */
.theme-paper .footer__love {
  color: #000;
  text-shadow: 1px 1px 0 rgba(255, 255, 255, .9);
}

/* Where the homepage keeps its astronaut, same bob, same 40px — but this page
   signs off with the stripper. */
.mascot {
  position: relative;
  z-index: 2;
  margin: -12px 0 0;
  padding-bottom: 26px;
  text-align: center;
  line-height: 0;
}
.mascot img { width: auto; height: 96px; }   /* portrait gif — 40px reads as a smudge */

@media (prefers-reduced-motion: no-preference) {
  .mascot img { animation: bob 3.4s ease-in-out infinite alternate; }
}
@keyframes bob { to { transform: translateY(-9px); } }

/* ------------------------------------------------------------------ small */
@media (max-width: 720px) {
  .bylaws { padding-top: 72px; }
  /* No pointer to follow — the dock spans the bottom of the screen and a tap
     picks directly. */
  .propose {
    right: 10px;
    left: 10px;
    bottom: 10px;
    max-width: none;
  }
  .propose__toggle { padding: 14px 18px; font-size: 16px; }
  /* Room under the mascot so the dock never sits on top of the footer. */
  .theme-paper { padding-bottom: 96px; }
  .paper-btn--corner { top: 14px; left: 12px; }
  .stamp { top: 14px; right: 12px; }
  .stamp__face { padding: 10px 20px; font-size: 12px; letter-spacing: 1px; }
  /* 30px per level eats a narrow screen alive by the fourth subsection. */
  .node--section,
  .node--subsection { margin-left: 16px; }
  .grid { font-size: 13px; }
}
