/* ============================================================================
   v24-components.css — the parts TWO OR MORE archetypes need.
   ----------------------------------------------------------------------------
   THE ADMISSION TEST

   A component belongs here only if two or more archetypes use it. One
   archetype's part lives in that archetype's sheet. This is not tidiness: a
   shared sheet is loaded by every page that loads it, and a rule that serves
   one page is bytes every other page downloads to style nothing.

   The site had already paid for that mistake — learn.css was being fetched by
   index.html, which uses not one .ln-* class: 5KB requested on the most
   important page on the site to style nothing at all.

   And the opposite mistake is just as real. A component that exists so a rule
   can be written for it later is a class nothing styles, which is why
   tools/verify_style_coverage.py exists.
   ============================================================================ */

/* --- notices ---------------------------------------------------------------
   The variance notice is the most-repeated element on this site: it appears on
   91 festival pages and every observance page, and it is the sentence that
   keeps a description from reading as a ruling. It is a component because it
   must look and read identically everywhere — a notice that varies is a notice
   a reader stops seeing. */
.sp-note {
  padding: var(--sp-4);
  border-radius: var(--sp-r-sm);
  background: var(--sp-raised);
  border: 1px solid var(--sp-line);
  font-size: var(--sp-t-sm);
  color: var(--sp-ink-2);
  margin-bottom: var(--sp-5);
}
.sp-note > :last-child { margin-bottom: 0; }
.sp-note strong { color: var(--sp-ink); }
.sp-note-vary { border-left: 3px solid var(--sp-bronze); }
.sp-note-caution { border-left: 3px solid var(--sp-caution); }

/* --- when a document was last looked at ------------------------------------
   Every policy, standards and methodology page carries one, and it is the line
   that decides whether a reader trusts the page. It is given a rule beneath it
   because it belongs to the HEAD of the document, not to the first paragraph:
   without one, "Last updated: 14 August 2026" reads as the opening sentence. */
.sp-updated {
  font-size: var(--sp-t-sm);
  color: var(--sp-ink-3);
  margin: 0 0 var(--sp-6);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--sp-line);
}

/* --- a button that is a link -----------------------------------------------
   The cookie and data-request pages open a preferences dialog from inside a
   sentence. It has to be a <button> — it performs an action and does not
   navigate — and it has to read as a link, because that is what it looks like
   it is. Resetting the element rather than restyling the text is what keeps
   the two in step when either changes. */
.sp-linklike {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--sp-accent);
  text-decoration: underline;
  text-underline-offset: 0.16em;
  cursor: pointer;
  min-height: 24px;      /* SC 2.5.8: the TARGET, not the text */
}
.sp-linklike:hover { color: var(--sp-accent-deep); }

/* --- an aside at body width ------------------------------------------------ */
.sp-small { font-size: var(--sp-t-sm); color: var(--sp-ink-3); }

/* --- a data table that stops being a table on a phone ----------------------
   RECOVERED, NOT INVENTED. This is `.ctab` from the sheet retired in Gate 3,
   rewritten on the v24 tokens. The first pass of that migration deleted the
   class on the grounds that v24-base.css already styles every <table> — true
   of the desktop rendering, and wrong about the part that mattered. The build
   said so on the next run: `/cookies.html @390: 240px of horizontal overflow`.

   A six-column table of cookie names, types, retention and categories cannot
   be read on a 390px screen as a table. Below 640px each row becomes a card
   and each cell grows its own label from `data-l`, so the reader gets six
   labelled facts instead of a sideways scroll through a grid whose header has
   left the screen.

   THE MARKUP CONTRACT: every <td> carries data-l="<the column's heading>".
   Without it the stacked cards are unlabelled, which is worse than the scroll.
   tools/verify_pages.js is what catches the overflow if this rule is lost
   again; nothing catches a missing data-l but reading the page, so it is
   stated here. */
.sp-table-stack code {
  font-size: 0.9em;
  background: var(--sp-quiet);
  padding: 1px var(--sp-1);
  border-radius: var(--sp-r-sm);
}
@media (max-width: 40rem) {
  .sp-table-stack,
  .sp-table-stack tbody,
  .sp-table-stack tr,
  .sp-table-stack td { display: block; width: 100%; }
  /* The caption keeps `display: table-caption` unless it is told otherwise,
     and a table-caption inside a table that is no longer a table shrink-wraps
     to its longest word. It rendered one word per line. */
  .sp-table-stack caption { display: block; }
  /* The header row is removed from the flow rather than hidden, so a screen
     reader still announces it and a sighted reader is not shown it twice. */
  .sp-table-stack thead {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .sp-table-stack tr {
    margin-bottom: var(--sp-4);
    border: 1px solid var(--sp-line);
    border-radius: var(--sp-r);
    overflow: hidden;
    background: var(--sp-raised);
  }
  .sp-table-stack td {
    border: 0;
    border-bottom: 1px solid var(--sp-line);
  }
  .sp-table-stack td:last-child { border-bottom: 0; }
  .sp-table-stack tbody tr:nth-child(even) { background: var(--sp-raised); }
  .sp-table-stack td::before {
    content: attr(data-l);
    display: block;
    font-family: var(--sp-sc);
    font-size: var(--sp-t-eyebrow);
    letter-spacing: var(--sp-track-eyebrow);
    text-transform: uppercase;
    color: var(--sp-ink-3);
    margin-bottom: var(--sp-1);
  }
}

/* --- the block that ends a reading page ------------------------------------
   PROMOTED FROM THE ARCHETYPE LAYER, which is the direction a component is
   supposed to travel. It was .ln-ask, written for the Sacred Knowledge
   teachings; the standards and methodology pages close with the same object
   under the name .page-cta, and two archetypes using one object is the
   admission test at the top of this file.

   It is deliberately not a banner. No urgency, no scarcity, no countdown — a
   reader who has just finished a page about how this site decides things
   should not be hurried at the bottom of it. */
.sp-ask {
  border: 1px solid var(--sp-line);
  border-radius: var(--sp-r);
  background: var(--sp-quiet);
  padding: var(--sp-5);
  margin: var(--sp-sec-tight) 0 0;
}
.sp-ask > :is(h2, h3):first-child { margin-top: 0; }
.sp-ask > p { margin-bottom: var(--sp-4); }
/* Paper cannot be clicked. */
@media print { .sp-ask { display: none; } }

/* --- cards -----------------------------------------------------------------
   A card is a surface with a label, a title and a line about it. It is NOT a
   layout: .sp-grid does that, and a card does not know how wide it is. */
.sp-card {
  display: block;
  padding: var(--sp-5);
  background: var(--sp-raised);
  border: 1px solid var(--sp-line);
  border-radius: var(--sp-r);
  text-decoration: none;
  color: inherit;
}
a.sp-card {
  transition: border-color var(--sp-dur-fast) var(--sp-ease),
              transform var(--sp-dur-fast) var(--sp-ease);
}
a.sp-card:hover { border-color: var(--sp-gold); transform: translateY(-1px); }
a.sp-card:hover .sp-card-t { color: var(--sp-accent-deep); }
.sp-card-k {
  font-family: var(--sp-sc);
  font-size: var(--sp-t-eyebrow);
  letter-spacing: var(--sp-track-eyebrow);
  text-transform: uppercase;
  color: var(--sp-ink-3);
  margin: 0 0 var(--sp-2);
}
.sp-card-t {
  font-family: var(--sp-display);
  font-size: var(--sp-t-lg);
  line-height: var(--sp-lh-snug);
  color: var(--sp-ink);
  margin: 0 0 var(--sp-2);
}
.sp-card-d {
  font-size: var(--sp-t-sm);
  color: var(--sp-ink-2);
  margin: 0;
  line-height: 1.55;
}

/* --- a hairline list, which is NOT a grid of cards -------------------------
   Most of what this site links to is a list of things with a name and a line
   about them, and a hairline list reads faster and scrolls shorter than the same
   content in boxes. The Sacred Knowledge hub was twenty boxes; it is now a set
   of paths, and this is what carries them. */
.sp-list { display: grid; gap: 0; list-style: none; margin: 0; padding: 0; }
.sp-list > li {
  display: grid;
  gap: var(--sp-1);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--sp-line);
  margin: 0;
}
.sp-list > li:last-child { border-bottom: 0; }
.sp-list-t { font-size: var(--sp-t-body); color: var(--sp-ink); }
.sp-list-d { font-size: var(--sp-t-sm); color: var(--sp-ink-2); }
.sp-list-lead {
  font-family: var(--sp-sc);
  font-size: var(--sp-t-eyebrow);
  letter-spacing: var(--sp-track-eyebrow);
  text-transform: uppercase;
  color: var(--sp-ink-3);
}
/* A labelled list puts the lead in its own column once there is room for one. */
@media (min-width: 42rem) {
  .sp-list-labelled > li {
    grid-template-columns: 7.5rem 1fr;
    column-gap: var(--sp-4);
  }
  .sp-list-labelled > li > .sp-list-lead { grid-row: span 3; }
}

/* --- buttons ---------------------------------------------------------------
   One action colour, one shape. The estate could render the same button as a
   pill on one page and a square on another depending on which bundle loaded. */
.sp-cta, .sp-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--sp-r);
  border: 1px solid transparent;
  font-family: var(--sp-sc);
  font-size: var(--sp-t-sm);
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background var(--sp-dur-fast) var(--sp-ease),
              border-color var(--sp-dur-fast) var(--sp-ease);
}
.sp-cta {
  background: var(--sp-maroon);
  color: var(--sp-ground);
}
.sp-cta:hover { background: var(--sp-maroon-deep); color: var(--sp-ground); }
.sp-btn {
  background: transparent;
  color: var(--sp-ink);
  border-color: var(--sp-line-strong);
}
.sp-btn:hover { border-color: var(--sp-gold); color: var(--sp-ink); }

/* --- tags ------------------------------------------------------------------ */
.sp-tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.sp-tag {
  display: inline-block;
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--sp-line-strong);
  border-radius: 999px;
  font-family: var(--sp-sc);
  font-size: var(--sp-t-xs);
  letter-spacing: 0.03em;
  color: var(--sp-ink-2);
  text-decoration: none;
}
a.sp-tag:hover { border-color: var(--sp-gold); color: var(--sp-ink); }
.sp-tag-solid {
  background: var(--sp-bronze);
  border-color: var(--sp-bronze);
  color: var(--sp-ground);
}

/* --- background reading: the teachings a page uses ------------------------
   Written by tools/apply_learn_links.py on the calendar, Panchāṅgam, muhūrtham
   and guide pages. A hairline list, not cards: it is a short shelf of further
   reading, and it should sit quietly under the page it serves. */
.sp-reading { margin: var(--sp-sec-tight) 0 0; }
.sp-reading .sp-list { margin-top: var(--sp-3); }
.sp-reading .sp-list-t { font-weight: 600; text-decoration: underline; text-underline-offset: 0.18em; }
/* inside .prose (the wedding muhūrtham guide) the list must not pick up the
   article's bullets and indent */
.sp-reading .sp-list { padding-left: 0; }
.sp-reading .sp-list > li { list-style: none; padding-left: 0; }
.sp-reading .sp-list > li::before { content: none; }
@media print { .sp-reading { display: none; } }

/* --- "more" link at the end of a section -----------------------------------
   DELIBERATELY NOT for a link inside a row. On 216 consecutive observance rows
   this treatment shouted louder than the observance names above it; a row wants
   an ordinary link at body size, which the base layer already gives it. */
.sp-more {
  display: inline-block;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--sp-line);
  font-family: var(--sp-sc);
  font-size: var(--sp-t-sm);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* --- breadcrumb ------------------------------------------------------------ */
.crumb {
  font-size: var(--sp-t-sm);
  color: var(--sp-ink-3);
  margin-bottom: var(--sp-4);
}
/* Gate 7: the breadcrumb links were 16 px tall — the single most common
   target under WCAG 2.5.8's 24 px minimum, on almost every page and at every
   width, and accessibility.html states that targets are at least 24×24. The
   padding makes each link a 24 px target without changing the text. */
.crumb a { color: var(--sp-ink-3); display: inline-block; padding-block: 4px; }
.crumb a:hover { color: var(--sp-accent); }

/* --- provenance strips -----------------------------------------------------
   How this site says HOW IT KNOWS a thing, and the distinction is load-bearing:
   a date that was computed and a date that was curated are known in different
   ways, and a reader is entitled to be told which. */
.sp-prov {
  font-family: var(--sp-sc);
  font-size: var(--sp-t-xs);
  letter-spacing: 0.03em;
  color: var(--sp-ink-3);
  margin: var(--sp-2) 0 var(--sp-4);
}
.sp-prov::before {
  content: '';
  display: inline-block;
  width: var(--sp-2); height: var(--sp-2);
  margin-right: var(--sp-2);
  border-radius: 50%;
  vertical-align: 0.05em;
  background: currentColor;
}
.sp-prov-computed  { color: var(--sp-good); }
.sp-prov-editorial { color: var(--sp-ink-3); }
.sp-prov-confirmed { color: var(--sp-bronze); }

/* --- the 2028 held-dates list on the festival calendar (v25.1) ------------
   A plain disclosure, closed by default: the list is a reference for the
   family looking for one date, not a banner. */
.held28 { margin: var(--sp-sec-tight) 0 0; }
.held28 > p { max-width: 68ch; }
.held28 details { margin-top: var(--sp-3); }
.held28 summary { cursor: pointer; padding-block: 6px; font-weight: 600; }
.held28 .sp-list-t a { font-weight: 600; }
