/* ---------------------------------------------------------------------------
   Brand

   Olympic33's two brand inks, taken from the 2026 logo files:
     #00415a  deep teal   — the dark mark, for light backgrounds
     #03ffff  cyan        — the light mark, for dark backgrounds

   The logo files are named for their INK, not their background, which is the
   opposite of how they are used. They are copied in here renamed for the
   background they belong on, so the mistake can't be made twice.
   --------------------------------------------------------------------------- */

:root {
  --o33-brand:      #00415a;
  --o33-brand-cyan: #03ffff;
}

/* Swap the wordmark with the theme. The template renders a single
   <img id="logo" src="logo.svg">, and an <img> is a separate document — it
   cannot see [data-bs-theme] on the host. So the mark is drawn as a
   background on the brand link instead, which the theme toggle does reach. */
.navbar-brand > img#logo { display: none; }

.navbar-brand::before {
  content: "";
  display: inline-block;
  width: 148px;
  height: 27px;
  margin-right: 0.6rem;
  vertical-align: -0.4rem;
  background: url("olympic33-on-light.svg") left center / contain no-repeat;
}
[data-bs-theme="dark"] .navbar-brand::before {
  background-image: url("olympic33-on-dark.svg");
}

/* ---------------------------------------------------------------------------
   O33 Commerce documentation — design tokens.

   One colour per ROLE, used identically in prose badges and in every mermaid
   diagram, so a reader learns the language once. The mermaid triples to paste
   are listed in docs/site/README.md.

     external   indigo   an ERP, a payment provider, Azure — not ours
     commerce   teal     this platform
     surface    amber    a client of the API — storefront, portal, integrator
     data       violet   a database, a queue, a search index
     gap        rose     a known gap, or a trap worth stopping at
     neutral    slate    structure, boundaries, anything unclassified
   --------------------------------------------------------------------------- */

:root {
  --o33-external:     #4f46e5;
  --o33-external-bg:  #eef2ff;
  --o33-external-ink: #1e1b4b;

  --o33-commerce:     #00415a;  /* the brand ink — this platform is the brand */
  --o33-commerce-bg:  #e8f4f9;
  --o33-commerce-ink: #002230;

  --o33-surface:      #b45309;
  --o33-surface-bg:   #fffbeb;
  --o33-surface-ink:  #451a03;

  --o33-data:         #7c3aed;
  --o33-data-bg:      #f5f3ff;
  --o33-data-ink:     #2e1065;

  --o33-gap:          #be123c;
  --o33-gap-bg:       #fff1f2;
  --o33-gap-ink:      #4c0519;

  --o33-neutral:      #64748b;
  --o33-neutral-bg:   #f8fafc;
  --o33-neutral-ink:  #0f172a;
}

[data-bs-theme="dark"] {
  --o33-external-bg:  #1e1b4b;
  --o33-external-ink: #e0e7ff;
  --o33-commerce-bg:  #00293a;
  --o33-commerce-ink: #b3f7ff;
  --o33-surface-bg:   #451a03;
  --o33-surface-ink:  #fef3c7;
  --o33-data-bg:      #2e1065;
  --o33-data-ink:     #ede9fe;
  --o33-gap-bg:       #4c0519;
  --o33-gap-ink:      #ffe4e6;
  --o33-neutral-bg:   #1e293b;
  --o33-neutral-ink:  #e2e8f0;
}

/* Links are brand teal. In dark mode the brand cyan (#03ffff) is too saturated
   for body-sized text — it vibrates against a dark ground — so links use a
   softened cyan and the pure brand colour is kept for the mark and for strokes. */
body {
  --bs-link-color-rgb: 0, 65, 90;
  --bs-link-hover-color-rgb: 0, 97, 133;
}
[data-bs-theme="dark"] body {
  --bs-link-color-rgb: 102, 224, 230;
  --bs-link-hover-color-rgb: 3, 255, 255;
}

/* ---------------------------------------------------------------------------
   Badges. <span class="pill core">Product core</span>

   Three states, and they are the point of the whole exercise: a reader should
   be able to tell at a glance what a second client inherits for free, what is
   bespoke to one client, and what is a switch.
   --------------------------------------------------------------------------- */

.pill {
  display: inline-block;
  padding: 0.12em 0.6em;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.6;
  white-space: nowrap;
  border: 1px solid transparent;
  vertical-align: baseline;
}

.pill.core    { background: var(--o33-commerce-bg); color: var(--o33-commerce-ink); border-color: var(--o33-commerce); }
.pill.client  { background: var(--o33-surface-bg);  color: var(--o33-surface-ink);  border-color: var(--o33-surface); }
.pill.config  { background: var(--o33-external-bg); color: var(--o33-external-ink); border-color: var(--o33-external); }
.pill.gap     { background: var(--o33-gap-bg);      color: var(--o33-gap-ink);      border-color: var(--o33-gap); }

/* ---------------------------------------------------------------------------
   Lead paragraph — the one-sentence framing under a page title.
   --------------------------------------------------------------------------- */

article .lead-frame {
  border-left: 3px solid var(--o33-commerce);
  background: var(--o33-commerce-bg);
  color: var(--o33-commerce-ink);
  padding: 0.9rem 1.1rem;
  margin: 1.25rem 0 1.75rem;
  border-radius: 0 6px 6px 0;
  font-size: 1.05rem;
}
article .lead-frame p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Ownership split — a two-column "theirs / ours" block.
   --------------------------------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0;
}
.split > div {
  padding: 1rem 1.1rem;
  border-radius: 8px;
  border: 1px solid var(--o33-neutral);
  background: var(--o33-neutral-bg);
}
.split > div.theirs { border-color: var(--o33-external); background: var(--o33-external-bg); color: var(--o33-external-ink); }
.split > div.ours   { border-color: var(--o33-commerce); background: var(--o33-commerce-bg); color: var(--o33-commerce-ink); }
.split h4 { margin: 0 0 0.5rem; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.75; }
.split ul { margin: 0; padding-left: 1.1rem; }
.split li { margin: 0.15rem 0; }

/* ---------------------------------------------------------------------------
   Hero — the one line that says what this is, above everything else.
   --------------------------------------------------------------------------- */

/* A pull statement, not a competing headline — the opening paragraph above it
   is the page's actual answer to "what is this". */
article .hero {
  margin: 1.75rem 0 2rem;
  padding: 1.1rem 0 1.1rem 1.4rem;
  border-left: 4px solid var(--o33-commerce);
}
article .hero h2 {
  border: 0;
  margin: 0 0 0.5rem;
  padding: 0;
  font-size: clamp(1.25rem, 1.05rem + 0.9vw, 1.6rem);
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--o33-commerce);
}
[data-bs-theme="dark"] article .hero h2 { color: var(--o33-commerce-ink); }
article .hero p {
  font-size: 1.02rem;
  max-width: 62ch;
  margin: 0;
}

/* Route subtitle under a page title — the name is the heading, the path is
   the detail, not the other way round. */
article p.route {
  margin: -0.6rem 0 1.4rem;
  font-size: 0.95rem;
  opacity: 0.72;
}
article p.route code { font-size: 0.9em; }

/* ---------------------------------------------------------------------------
   Fact strip — the four or five things a reader wants confirmed immediately.
   --------------------------------------------------------------------------- */

ul.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.55rem;
  list-style: none;
  margin: 1.1rem 0 1.75rem;   /* bottom margin matters — a heading often follows */
  padding: 0;
}
ul.facts li {
  font-size: 0.85rem;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--o33-neutral-bg);
  border: 1px solid var(--o33-neutral);
  color: var(--o33-neutral-ink);
}
ul.facts li b {
  font-weight: 650;
  opacity: 0.65;
  margin-right: 0.3rem;
}

/* ---------------------------------------------------------------------------
   Glossary — available immediately, but folded so it doesn't interrupt.
   --------------------------------------------------------------------------- */

details.glossary {
  margin: 1.5rem 0 2rem;
  border: 1px solid var(--o33-neutral);
  border-radius: 8px;
  background: var(--o33-neutral-bg);
}
details.glossary > summary {
  cursor: pointer;
  padding: 0.7rem 1rem;
  font-weight: 600;
  font-size: 0.95rem;
  list-style: none;
}
details.glossary > summary::-webkit-details-marker { display: none; }
details.glossary > summary::before {
  content: "\25B8";                 /* ▸ — a character, not an icon-font codepoint */
  font-size: 0.9rem;
  margin-right: 0.5rem;
  display: inline-block;
  transition: transform 0.15s ease;
  color: var(--o33-commerce);
}
details.glossary[open] > summary::before { transform: rotate(90deg); }
details.glossary > :not(summary) { margin: 0 1rem 1rem; }
details.glossary table { margin-bottom: 0; }

/* Icons in card kickers. */
.cards .k i { margin-right: 0.35rem; opacity: 0.9; }

/* ---------------------------------------------------------------------------
   Card grid — short value props and capability groups.
   Chosen over the tab strip a marketing page would use: tabs hide five of six
   groups from both the eye and the search index.
   --------------------------------------------------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0 2rem;
}
.cards > div {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--o33-neutral);
  border-top: 3px solid var(--o33-commerce);
  border-radius: 8px;
  background: var(--o33-neutral-bg);
}
.cards h4 {
  margin: 0 0 0.45rem;
  font-size: 1rem;
  font-weight: 650;
  line-height: 1.35;
}
.cards p  { margin: 0; font-size: 0.93rem; }
.cards ul { margin: 0.4rem 0 0; padding-left: 1.05rem; font-size: 0.9rem; }
.cards li { margin: 0.12rem 0; }
.cards .k {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-bottom: 0.3rem;
}

/* ---------------------------------------------------------------------------
   Capability-block diagram. Lanes of labelled blocks, in the style of a
   runtime architecture chart. HTML rather than an image or a mermaid graph so
   it stays searchable, selectable, theme-aware and readable on a phone.
   --------------------------------------------------------------------------- */

.arch {
  display: grid;
  gap: 0.7rem;
  margin: 1.5rem 0 2rem;
}
.arch .lane {
  border: 1px solid var(--o33-neutral);
  border-radius: 8px;
  overflow: hidden;
}
.arch .lane > h5 {
  margin: 0;
  padding: 0.4rem 0.8rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  background: var(--o33-neutral-bg);
  color: var(--o33-neutral-ink);
  border-bottom: 1px solid var(--o33-neutral);
}
.arch .lane > h5 span { font-weight: 500; text-transform: none; letter-spacing: 0; opacity: 0.65; }
.arch .blocks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 0.45rem;
  padding: 0.55rem;
}
.arch .blk {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 3rem;
  border: 1px solid var(--o33-neutral);
  border-radius: 6px;
  padding: 0.45rem 0.55rem;
  font-size: 0.83rem;
  line-height: 1.3;
  text-align: center;
  background: var(--o33-neutral-bg);
  color: var(--o33-neutral-ink);
}
.arch .blk b { font-weight: 620; }

/* Routes are shown as code. Inside a coloured block the default code chip
   (its own background and ink) fights the block, so it inherits instead —
   keeping only the monospace face, which is what marks it as a path. */
.arch .blk code {
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font-size: 0.95em;
}
.arch .blk small { display: block; font-size: 0.71rem; opacity: 0.72; margin-top: 0.1rem; }

.arch .blk.commerce { background: var(--o33-commerce-bg); color: var(--o33-commerce-ink); border-color: var(--o33-commerce); }
.arch .blk.framework { background: var(--o33-neutral-bg); color: var(--o33-neutral-ink); border-color: var(--o33-neutral); }
.arch .blk.external { background: var(--o33-external-bg); color: var(--o33-external-ink); border-color: var(--o33-external); }
.arch .blk.surface  { background: var(--o33-surface-bg);  color: var(--o33-surface-ink);  border-color: var(--o33-surface); }
.arch .blk.data     { background: var(--o33-data-bg);     color: var(--o33-data-ink);     border-color: var(--o33-data); }

.arch .lane.commerce { border-color: var(--o33-commerce); }
.arch .lane.external { border-color: var(--o33-external); }
.arch .lane.surface  { border-color: var(--o33-surface); }
.arch .lane.data     { border-color: var(--o33-data); }

/* Sub-rows within a lane.
   NOT called .row — Bootstrap owns that class and gives it negative left and
   right margins, which pushes blocks past the lane padding where the lane's
   overflow:hidden then clips their borders off. */
.arch .lane .tier { padding: 0 0.55rem; }
.arch .lane .tier > h6 {
  margin: 0.5rem 0 0.3rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.55;
}
/* auto-FILL, not auto-fit: empty tracks are kept, so the four tiers inside
   Commerce Core share one column grid and their blocks line up vertically.
   auto-fit would collapse the empty tracks and stretch each tier differently. */
.arch .lane .tier .blocks {
  padding: 0 0 0.55rem;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}

/* ---------------------------------------------------------------------------
   Commerce Core sits beside the services it calls, rather than above them —
   a side panel reads as "these are things we talk to", a lane below reads as
   "these come next", which is wrong.
   --------------------------------------------------------------------------- */

.arch .pair {
  display: grid;
  gap: 0.7rem;
  grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .arch .pair {
    grid-template-columns: minmax(0, 1fr) minmax(180px, 240px);
    align-items: start;
  }
  /* In the narrow side panel one block per row reads better than a cramped grid. */
  .arch .pair > .lane.external .blocks { grid-template-columns: 1fr; }
  .arch .pair > .lane.external .blk { min-height: 0; text-align: left; }
}

/* Marks a block that owns a database context — makes "12 contexts" visible. */
.arch .blk .owns {
  color: var(--o33-data);
  font-size: 0.62rem;
  vertical-align: 0.35em;
  margin-left: 0.2rem;
}

/* ---------------------------------------------------------------------------
   Legend. Colour encodes OWNERSHIP, not layer — the sub-headings already say
   which layer a block is in, so spending colour on that says nothing twice.
   --------------------------------------------------------------------------- */

ul.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  font-size: 0.82rem;
}
ul.legend li { display: flex; align-items: center; gap: 0.4rem; }
ul.legend .sw {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  border: 1px solid;
  display: inline-block;
  flex: none;
}
ul.legend .sw.commerce  { background: var(--o33-commerce-bg); border-color: var(--o33-commerce); }
ul.legend .sw.framework { background: var(--o33-neutral-bg);  border-color: var(--o33-neutral); }
ul.legend .sw.external  { background: var(--o33-external-bg); border-color: var(--o33-external); }
ul.legend .sw.data      { background: var(--o33-data-bg);     border-color: var(--o33-data); }
ul.legend .sw.surface   { background: var(--o33-surface-bg);  border-color: var(--o33-surface); }

/* A thin arrow between lanes. */
.arch .flow {
  text-align: center;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--o33-neutral);
  margin: -0.25rem 0;
}

/* Tables read better a little tighter than the Bootstrap default. */
article table { font-size: 0.94rem; }
article table th { white-space: nowrap; }

/* Markdown has no way to write a table without a header row, so a label/value
   table is written `| | |` and renders an empty band above the content. Hide
   the header when no cell in it has any text. A comparison matrix — where the
   first heading is blank but the rest are not — is untouched. */
article table thead:not(:has(th:not(:empty))) { display: none; }

/* First column of a headerless table is a label, so let it size to content. */
article table thead:not(:has(th:not(:empty))) + tbody td:first-child {
  white-space: nowrap;
  width: 1%;
}

/* Mermaid diagrams shouldn't push the page sideways on a phone. */
article .mermaid { overflow-x: auto; }
