/* ==========================================================================
   theme.css — one structure, many skins.
   Every theme must express itself entirely through the tokens below.
   If a theme needs different HTML, it is not a theme; it is a second site.
   ========================================================================== */

/* --- Token contract -------------------------------------------------------
   Colour is the easy half. The tokens that actually let a 1998 portal and a
   quiet serif page share markup are the SHAPE tokens: --panel-border,
   --rule, --radius, --panel-head-display. Themes swap bevels for hairlines
   without any rule in the component layer changing.
   -------------------------------------------------------------------------- */

:root,
[data-theme="portal"] {
  --font-display: "Times New Roman", Times, serif;
  --font-body:    "Times New Roman", Times, serif;
  --font-ui:      Verdana, Arial, sans-serif;
  --font-mono:    "Courier New", monospace;

  --size-display: 24px;
  --size-body:    12.5px;
  --size-ui:      11px;
  --leading:      1.45;
  --gap:          15px;
  --stack:        12px;

  --bg:            #ffffff;
  --fg:            #000000;
  --fg-muted:      #666666;
  --link:          #0000ee;
  --link-visited:  #551a8b;

  --panel-bg:        #ffffcc;
  --panel-head-bg:   #eeee99;
  --panel-head-fg:   #333300;
  --panel-border:    2px outset #cccccc;
  --panel-head-rule: 1px solid #999966;
  --panel-head-display: block;   /* set to none to drop title bars entirely */

  --field-border: 2px inset #cccccc;
  --field-bg:     #ffffff;
  --btn-border:   2px outset #cccccc;
  --btn-bg:       #dddddd;

  --rule:   1px solid #000000;
  --hair:   1px solid #cccccc;
  --radius: 0;

  --counter-bg:     #000000;
  --counter-fg:     #00ff00;
  --counter-font:   var(--font-mono);
  --counter-border: 2px inset #cccccc;
}

/* Quiet serif — the restrained version. Same markup, no costume. */
[data-theme="plain"] {
  --font-display: Georgia, "Times New Roman", serif;
  --font-body:    Georgia, "Times New Roman", serif;
  --font-ui:      Georgia, serif;
  --font-mono:    ui-monospace, "SF Mono", Menlo, monospace;

  --size-display: 30px;
  --size-body:    16px;
  --size-ui:      13px;
  --leading:      1.6;
  --gap:          32px;
  --stack:        22px;

  --bg:           #fdfdfc;
  --fg:           #1a1a1a;
  --fg-muted:     #6b6b6b;
  --link:         #1a4fa0;
  --link-visited: #6b4a8f;

  --panel-bg:        transparent;
  --panel-head-bg:   transparent;
  --panel-head-fg:   #1a1a1a;
  --panel-border:    none;
  --panel-head-rule: 1px solid #d8d8d4;
  --panel-head-display: block;

  --field-border: 1px solid #c8c8c4;
  --field-bg:     #ffffff;
  --btn-border:   1px solid #1a1a1a;
  --btn-bg:       transparent;

  --rule:   1px solid #1a1a1a;
  --hair:   1px solid #e4e4e0;
  --radius: 0;

  --counter-bg:     transparent;
  --counter-fg:     #6b6b6b;
  --counter-font:   var(--font-mono);
  --counter-border: none;
}

/* --- Component layer: reads tokens only, never literal values ------------- */

/* An explicit `display:` on a component beats the [hidden] attribute, so a
   hidden element keeps rendering. The counter hit this. Guard it once, here,
   rather than per-component. */
[hidden] { display: none !important; }

/* Deliberately a shared token, not a per-theme one: a theme may restyle but
   must never relayout. Not in ch either — ch is the width of the "0" glyph, so
   it scales with font-size, and one number gave 487px in portal (12.5px Times)
   but 766px in plain (16px Georgia). */
:root { --measure: 62rem; }

body {
  margin: 0 auto;
  padding: 16px;
  max-width: var(--measure);
  background: var(--bg);
  color: var(--fg);
  font: var(--size-body)/var(--leading) var(--font-body);
}

a               { color: var(--link); }
a:visited       { color: var(--link-visited); }
a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.masthead        { text-align: center; margin-bottom: 6px; }
.masthead h1     { font: var(--size-display)/1.15 var(--font-display); margin: 0; font-weight: normal; }
.masthead.compact h1 { font-size: calc(var(--size-display) * 0.75); }
.rule            { border-top: var(--rule); margin-bottom: var(--stack); }
.crumb           { font: var(--size-ui)/1.4 var(--font-ui); color: var(--fg-muted); margin-bottom: var(--stack); }

.layout          { display: grid; grid-template-columns: 1fr 1fr 0.82fr; gap: var(--gap); }
/* Grid items default to min-width:auto, so a wide child (a tweet image)
   stops the column shrinking and the page scrolls sideways on mobile. */
.layout > *      { min-width: 0; }
.layout > aside  { grid-column: 3; }
/* index.php has two content divs and fills tracks 1-2. A page with a single
   content div would otherwise sit in one 162px track and leave track 2 empty —
   which is what squeezed the rules page into a five-word-wide ribbon. */
.layout > div:only-of-type { grid-column: 1 / 3; }

.cat             { margin-bottom: var(--stack); }
.cat > h2        { font: 500 calc(var(--size-body) * 1.2)/1.2 var(--font-display); margin: 0; }
.cat > h2 a      { text-decoration: underline; }
.cat > ul        { list-style: none; margin: 2px 0 0 9px; padding: 0; }
.cat > ul > li   { line-height: 1.5; }
.cat .note       { color: var(--fg-muted); }

.panel           { border: var(--panel-border); border-radius: var(--radius); background: var(--panel-bg); margin-bottom: var(--stack); }
.panel > h3      { display: var(--panel-head-display); margin: 0; padding: 2px 6px; text-align: center;
                   background: var(--panel-head-bg); color: var(--panel-head-fg);
                   border-bottom: var(--panel-head-rule);
                   font: 500 var(--size-ui)/1.5 var(--font-ui); }
.panel > .body   { padding: 6px 7px; }

.field           { border: var(--field-border); background: var(--field-bg); color: var(--fg);
                   font: var(--size-ui) var(--font-ui); padding: 2px 4px; border-radius: var(--radius); }
.btn             { border: var(--btn-border); background: var(--btn-bg); color: var(--fg);
                   font: var(--size-ui) var(--font-ui); padding: 2px 12px; border-radius: var(--radius); cursor: pointer; }

.tree            { border: var(--field-border); background: var(--field-bg);
                   font: var(--size-body)/1.55 var(--font-mono); padding: 8px 9px; overflow-x: auto; }

.counter         { display: inline-block; background: var(--counter-bg); color: var(--counter-fg);
                   border: var(--counter-border); font: 13px var(--counter-font);
                   letter-spacing: 2px; padding: 1px 4px; }
.site-footer     { border-top: var(--rule); margin-top: var(--stack); padding-top: 7px;
                   text-align: center; font: var(--size-ui)/1.5 var(--font-ui); color: var(--fg-muted); }

/* Homepage hero: photo + current quote, directly under the masthead. They
   rotate together, so they are laid out together. */
.hero            { display: flex; gap: var(--gap); align-items: flex-start; margin-bottom: var(--stack); }
.hero img        { width: 180px; max-width: 35%; height: auto; border: var(--panel-border); border-radius: var(--radius); }
.hero-text       { flex: 1; }
.hero .quote     { margin: 0 0 var(--stack) 0; font-style: italic; }
.cite            { color: var(--fg-muted); font-size: var(--size-ui); margin-left: 0.5em; font-style: normal; }

/* Form rows wrap a label and a control. The control itself carries .field —
   putting .field on the wrapper would draw the box around the label too. */
.formrow         { margin-bottom: var(--stack); }
.formrow label   { display: block; font: var(--size-ui)/1.4 var(--font-ui); color: var(--fg-muted); margin-bottom: 3px; }
.formrow .field  { width: 100%; box-sizing: border-box; }

/* Honeypot: humans never see it, bots fill it in. Not display:none, which
   some bots detect and skip. */
.hp              { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.contact         { margin-bottom: var(--stack); }
.contact summary { cursor: pointer; }
.contact-msg     { font: var(--size-ui)/1.4 var(--font-ui); }
.isms summary    { cursor: pointer; font: var(--size-ui)/1.4 var(--font-ui); }
.isms ul         { list-style: none; margin: var(--stack) 0 0 0; padding: 0; }
.isms li         { margin-bottom: var(--stack); }

@media (max-width: 640px) {
  .hero { flex-direction: column; }
  .hero img { max-width: 100%; }

  .layout { grid-template-columns: 1fr; }
  .layout > aside { grid-column: 1; }
  /* One track here: spanning 1/3 would invent a second one and scroll sideways. */
  .layout > div:only-of-type { grid-column: 1; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
