/*
 * famtec.ch stylesheet
 *
 * Taken from the binding mockup docs/design/mockup-1-warmes-archiv-v11.html.
 * Three things are handled elsewhere and were removed here:
 *
 *   - the colour variables come from configs/palette.yaml and are inlined
 *     into the document head per request, so the theme is correct in the
 *     first paint
 *   - the category accent mapping is generated from groups.yaml, so a new
 *     group needs no css
 *   - the one declaration that differed between the light and the dark
 *     mockup is now the --shadow-mark effect
 */

:root{
  --wrap-max:1440px;
  /* The width of a column of running text. Not used for layout here, only as
     the anchor for the way back - see the uplink rules at the end. */
  --prose-max:760px;
}

*{box-sizing:border-box;}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  line-height:1.5;
}

@media (prefers-reduced-motion: no-preference){
  .reveal{ animation:fadeUp .5s ease both; }
}
@keyframes fadeUp{
  from{ opacity:0; transform:translateY(10px); }
  to{ opacity:1; transform:translateY(0); }
}

/* Kopfbereich */
header.hero{
  max-width:var(--wrap-max);
  margin:0 auto;
  padding:56px 40px 32px;
  text-align:center;
}
.eyebrow{
  font-size:12px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--clay);
  font-weight:600;
  margin-bottom:10px;
}
h1{
  font-family:Georgia,"Iowan Old Style","Times New Roman",serif;
  font-size:clamp(30px,3.4vw,44px);
  margin:0 0 12px;
  letter-spacing:-.01em;
  text-shadow:var(--text-lift);
}
.subtitle{
  color:var(--ink-soft);
  font-size:16px;
  max-width:560px;
  margin:0 auto;
  min-height:24px;
}

/* Netzwerk-Status */
.status-wrap{
  max-width:var(--wrap-max);
  margin:0 auto;
  padding:0 40px 8px;
}
.status-card{
  background:var(--paper-raised);
  border:1px solid var(--line);
  border-radius:12px;
  padding:28px 24px 26px;
  text-align:center;
  box-shadow:var(--shadow-rest);
  animation-delay:.05s;
}
.status-head{
  margin-bottom:22px;
}
.status-left{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:12px;
}
.status-dot{
  width:12px;height:12px;
  border-radius:50%;
  flex-shrink:0;
}
.status-dot.on{
  background:var(--status-on);
  box-shadow:0 0 0 4px var(--status-on-soft);
}
@media (prefers-reduced-motion: no-preference){
  .status-dot.on{ animation:pulse 2.2s ease-in-out infinite; }
}
@keyframes pulse{
  0%,100%{ box-shadow:0 0 0 4px var(--status-on-soft); }
  50%{ box-shadow:0 0 0 8px transparent; }
}
.status-dot.off{
  background:var(--status-off);
  box-shadow:0 0 0 4px var(--status-off-soft);
}
.status-title{
  font-family:Georgia,serif;
  font-size:17px;
}
.status-title a{
  color:var(--pine);
  font-weight:600;
  text-decoration:underline;
  text-underline-offset:2px;
}
.status-title a:hover, .status-title a:focus-visible{
  color:var(--clay);
}
.status-toggle{
  font:inherit;
  font-size:12.5px;
  color:var(--ink-soft);
  background:transparent;
  border:1px dashed var(--line);
  border-radius:20px;
  padding:7px 16px;
  cursor:pointer;
  transition:border-color .15s ease, color .15s ease;
}
.status-toggle:hover, .status-toggle:focus-visible{
  border-color:var(--pine);
  color:var(--pine);
  outline:none;
}
.status-toggle[aria-pressed="true"]{
  border-style:solid;
  border-color:var(--pine);
  color:var(--pine);
}
.toggle-row{
  display:flex;
  justify-content:center;
  gap:10px;
  flex-wrap:wrap;
}
.nerd-panel{
  margin-top:20px;
  padding-top:18px;
  border-top:1px dashed var(--line);
}
.nerd-panel[hidden]{ display:none; }
.nerd-group + .nerd-group{ margin-top:18px; }
.nerd-label{
  font-size:10.5px;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--ink-soft);
  margin-bottom:10px;
}
.statrow.nerd{
  gap:18px 28px;
  margin-bottom:0;
}
.statrow.nerd .stat{ min-width:76px; }
.statrow.nerd .val{ font-size:13px; }

/* Status-Meldungen */
.messages-block{
  display:flex;
  flex-direction:column;
  gap:4px;
  margin:0 auto 18px;
  max-width:520px;
}
.messages-panel{
  display:flex;
  flex-direction:column;
  gap:4px;
  margin:6px auto 16px;
  max-width:520px;
  padding-top:14px;
  border-top:1px dashed var(--line);
}
.messages-panel[hidden]{ display:none; }
.message-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:14px;
  padding:8px 12px;
  border-radius:8px;
  border:none;
  background:transparent;
  font:inherit;
  color:var(--ink);
  text-align:left;
  cursor:pointer;
  width:100%;
  transition:background .15s ease;
}
.message-row:focus-visible{ outline:2px solid var(--line); outline-offset:2px; }
.msg-left{
  display:flex;
  align-items:center;
  gap:9px;
  min-width:0;
  font-size:13px;
}
.msg-subject{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.msg-meta{
  flex-shrink:0;
  font-size:11.5px;
  color:var(--ink-soft);
  white-space:nowrap;
}
@media (max-width: 1023px){
  .msg-meta{ display:none; }
}
.message-row .msg-dot{
  width:8px;height:8px;
  border-radius:50%;
  flex-shrink:0;
}
.message-row.incident .msg-dot{
  background:var(--incident);
  box-shadow:0 0 0 4px var(--incident-glow);
}
.message-row.incident:hover{ background:var(--incident-soft); }
.message-row.maintenance .msg-dot{
  background:var(--maint);
  box-shadow:0 0 0 4px var(--maint-glow);
}
.message-row.maintenance:hover{ background:var(--maint-soft); }
.message-row.available .msg-dot{
  background:var(--status-on);
  box-shadow:0 0 0 4px var(--status-on-soft);
}
@media (prefers-reduced-motion: no-preference){
  .message-row.available .msg-dot{ animation:pulse 2.2s ease-in-out infinite; }
}
.message-row.available:hover{ background:var(--status-on-soft); }
.message-row.unavailable .msg-dot{ background:var(--status-off); }
.message-row.unavailable:hover{ background:var(--status-off-soft); }
.messages-empty{
  font-size:12.5px;
  color:var(--ink-soft);
  padding:2px 12px;
  text-align:center;
}

/* Layover (Meldungs-Detail-Popup) */
.msg-overlay{
  position:fixed;
  inset:0;
  background:rgba(20,18,14,.4);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:24px;
  z-index:50;
}
.msg-overlay[hidden]{ display:none; }
.msg-overlay-card{
  position:relative;
  width:100%;
  max-width:420px;
  background:var(--paper-raised);
  border:1px solid var(--line);
  border-radius:14px;
  padding:26px 24px 22px;
  box-shadow:var(--shadow-lift);
  text-align:left;
}
.msg-overlay-close{
  position:absolute;
  top:12px;
  right:12px;
  width:28px;
  height:28px;
  border-radius:50%;
  border:1px solid var(--line);
  background:transparent;
  color:var(--ink-soft);
  font-size:15px;
  line-height:1;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  transition:border-color .15s ease, color .15s ease;
}
.msg-overlay-close:hover, .msg-overlay-close:focus-visible{
  border-color:var(--pine);
  color:var(--pine);
  outline:none;
}
.msg-overlay-type{
  display:inline-flex;
  align-items:center;
  gap:7px;
  font-size:11px;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--ink-soft);
  margin-bottom:10px;
}
.msg-overlay-type .msg-dot{ width:8px;height:8px;border-radius:50%; }
.msg-overlay-subject{
  font-family:Georgia,serif;
  font-size:18px;
  margin:0 0 10px;
  padding-right:20px;
}
.msg-overlay-body{
  font-size:14px;
  color:var(--ink-soft);
  line-height:1.6;
  margin:0 0 14px;
}
.msg-overlay-meta{
  font-size:11.5px;
  color:var(--ink-soft);
  border-top:1px solid var(--line);
  padding-top:10px;
}
.statrow{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:26px 36px;
  margin-bottom:22px;
}
.stat{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:4px;
  min-width:88px;
}
.stat .lbl{
  font-size:11px;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink-soft);
}
.stat .val{
  font-size:14.5px;
  font-weight:600;
}

/* Dienst-Kategorien */
main{
  max-width:var(--wrap-max);
  margin:0 auto;
  padding:8px 40px 80px;
}
.category{
  margin-top:44px;
}
.category-head{
  display:flex;
  align-items:baseline;
  gap:10px;
  margin:0 0 20px;
}
.swatch{
  width:9px;height:9px;
  border-radius:2px;
  margin-bottom:1px;
  background:var(--accent);
  flex-shrink:0;
}
@media (prefers-reduced-motion: no-preference){
  .swatch{ animation:swatchPulse 2.8s ease-in-out infinite; }
}
@keyframes swatchPulse{
  0%,100%{ box-shadow:0 0 0 0 var(--accent-glow); }
  50%{ box-shadow:0 0 0 5px transparent; }
}
.category h2{
  font-size:12.5px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-soft);
  font-weight:700;
  margin:0;
}
.category h2 em{
  font-style:normal;
  color:var(--ink);
  text-shadow:var(--text-lift);
}
.category-count{
  font-size:11.5px;
  color:var(--ink-soft);
}
.category-head::after{
  content:"";
  flex:1;
  height:1px;
  background:var(--line);
}

.tiles{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:18px;
}
.tile{
  width:172px;
  background:var(--paper-raised);
  border:1px solid var(--line);
  border-radius:12px;
  padding:20px 16px 18px;
  text-align:center;
  text-decoration:none;
  color:inherit;
  box-shadow:var(--shadow-rest);
  position:relative;
  transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.tile-badges{
  position:absolute;
  top:10px;
  right:10px;
  display:flex;
  gap:4px;
}
.tile-badge{
  display:flex;
  color:var(--ink-soft);
  transition:color .15s ease;
}
.tile:hover .tile-badge{ color:var(--ink); }
.badge-icon{
  width:14px;
  height:14px;
  flex-shrink:0;
}

/* Legende */
.legend-wrap{
  max-width:var(--wrap-max);
  margin:0 auto;
  padding:18px 40px 0;
}
.legend{
  display:flex;
  justify-content:center;
  flex-wrap:wrap;
  gap:10px 28px;
  font-size:12px;
  color:var(--ink-soft);
}
.legend-item{
  display:flex;
  align-items:center;
  gap:6px;
}
.legend-item .badge-icon{ color:var(--ink-soft); }
.tile:hover, .tile:focus-visible{
  transform:translateY(-4px);
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent-glow), 0 0 26px 2px var(--accent-glow), var(--shadow-lift);
  outline:none;
}
.tile .mark{
  width:44px;
  height:44px;
  margin:0 auto 12px;
  border-radius:50%;
  display:flex;
  align-items:center;
  justify-content:center;
  font-family:Georgia,serif;
  font-size:16px;
  font-weight:600;
  box-shadow:var(--shadow-mark);
  /* The circle clips whatever it holds, so a logo that is not round stays
     round on the tile. */
  overflow:hidden;
}
/* The circle was drawn for two characters. Three and four have to fit as well,
   because the admin tools are abbreviated by site (RMBB, FJBM). Equal size for
   all lengths is not the goal - fitting is. */
.tile .mark[data-mark-len="3"]{ font-size:13px; letter-spacing:-.02em; }
.tile .mark[data-mark-len="4"]{ font-size:11px; letter-spacing:-.03em; }
/* A logo keeps its own proportions and stays inside the circle; the spacing
   around it is baked into the file, not added here, so every icon carries the
   air its shape needs. */
.tile .mark-icon img{
  width:100%;
  height:100%;
  object-fit:contain;
}
/* A sprite mark instead of a logo. It is drawn in the accent of its tile
   rather than in its own colours, which is what an image file cannot do -
   and the reason the three browser check stages can be red, orange and green
   without three pairs of files for the two themes. */
.tile .mark-symbol svg{
  width:60%;
  height:60%;
}
.tile .mark-symbol{ color:var(--accent); }

/* A logo that is one colour on transparency - the Apple mark, the gear - would
   be black on a dark ground in dark mode. Turning it around costs one rule and
   one file instead of a second image per theme that has to be kept in step.
   The factor comes from palette.yaml, so it follows all three theme states:
   explicit light, explicit dark, and the system setting. */
.tile .mark-monochrome img{ filter:invert(var(--icon-invert,0)); }
.tile .name{
  font-family:Georgia,serif;
  font-size:15px;
  margin:0 0 4px;
  text-shadow:var(--text-lift);
}
.tile .desc{
  font-size:11.5px;
  color:var(--ink-soft);
  line-height:1.4;
}


.tile .mark{ background:var(--accent-soft); color:var(--accent); }

footer{
  max-width:var(--wrap-max);
  margin:0 auto;
  padding:0 40px 40px;
  color:var(--ink-soft);
  font-size:12px;
  text-align:center;
}

/* ---------------------------------------------------------------------------
 * Additions beyond the mockup.
 *
 * The mockup drives its panels with JavaScript. Server side rendering is
 * mandatory here, so the same panels are details/summary elements, which work
 * with scripting disabled. These rules make a summary look like the button the
 * mockup styled, and cover the two states the mockup does not show at all:
 * an unavailable service and the flag in front of a network label.
 * --------------------------------------------------------------------------- */

/* Links.
 *
 * The mockup only ever styles the single link in the status card, so every
 * other link fell back to the browser default blue. The same treatment is
 * applied globally here: nothing may drop out of the palette. The specificity
 * is low on purpose, so .tile (color:inherit) and the footer rules keep winning.
 */
a{
  color:var(--pine);
  text-decoration:underline;
  text-underline-offset:2px;
}
a:hover, a:focus-visible{ color:var(--clay); }

summary.status-toggle,
summary.message-row{
  list-style:none;
  cursor:pointer;
}
summary.status-toggle::-webkit-details-marker,
summary.message-row::-webkit-details-marker{ display:none; }
summary.status-toggle::marker,
summary.message-row::marker{ content:""; }

.nerd-details[open] .nerd-panel,
.messages-details[open] .messages-panel{ display:block; }

.message-entry{ width:100%; }
.message-body{
  margin:0 0 8px;
  padding:0 12px 4px 33px;
  font-size:12.5px;
  line-height:1.5;
  color:var(--ink-soft);
}

/* status "unavailable": visible but greyed out and not clickable
   (docs/config-management.md, "Ausblenden statt Ausgrauen" applies to the
   view filtering, not to the maturity of a service) */
.tile-unavailable{
  opacity:.55;
  pointer-events:none;
  cursor:default;
}

/* flag before the text, never instead of it */
.flag{
  vertical-align:-2px;
  margin-right:6px;
  border-radius:2px;
}

/* Legend spacing.
 *
 * The mockup leaves 26px between the status card and the legend but 52px
 * between the legend and the first category (8px below the card + 18px above
 * the legend, against 8px of main padding + 44px category margin below it).
 * That reads as if the legend belonged to the status card, although it is the
 * key to the badges on the tiles below.
 *
 * The proportion is turned around: 39px above, 26px below (18px here plus the
 * 8px of main padding). The legend now sits closer to what it explains.
 */
.legend-wrap{ padding:31px 40px 18px; }
.category:first-child{ margin-top:0; }

/* Footer navigation, same rules the drafts use. */
footer nav{ margin-bottom:8px; }
footer a{
  color:var(--ink-soft);
  margin:0 8px;
}
footer a[aria-current="page"]{
  color:var(--ink);
  font-weight:600;
}

.theme-switch{
  display:flex;
  justify-content:center;
  align-items:center;
  flex-wrap:wrap;
  gap:8px;
  font-size:12px;
  color:var(--ink-soft);
}
.theme-switch button{
  border:1px solid var(--line);
  background:var(--paper-raised);
  color:var(--ink-soft);
  border-radius:999px;
  padding:3px 10px;
  font:inherit;
  cursor:pointer;
}
.theme-switch button[aria-pressed="true"]{
  color:var(--ink);
  border-color:var(--ink-soft);
}


/* ---------------------------------------------------------------------------
 * Badge hints.
 *
 * A panel that opens on hover, and on keyboard focus in the legend, where the
 * badges are explained. On a tile the badge sits inside the link, so it gets
 * no tabindex of its own: interactive content nested in a link is a trap for
 * keyboard users, and the same explanation is one legend away.
 *
 * No JavaScript is involved, in line with the rest of the page.
 * --------------------------------------------------------------------------- */

.has-hint{ position:relative; }

.badge-hint{
  position:absolute;
  left:50%;
  bottom:calc(100% + 10px);
  transform:translateX(-50%);
  z-index:30;

  display:flex;
  flex-direction:column;
  gap:6px;
  width:max-content;
  min-width:170px;
  max-width:260px;

  padding:10px 12px;
  background:var(--paper-raised);
  border:1px solid var(--line);
  border-radius:8px;
  box-shadow:var(--shadow-lift);

  font-size:12px;
  line-height:1.45;
  font-weight:400;
  color:var(--ink-soft);
  text-align:left;
  text-transform:none;
  letter-spacing:normal;
  white-space:normal;

  opacity:0;
  visibility:hidden;
  transition:opacity .12s ease;
  /* The panel itself is never a hover target, which avoids it flickering when
     the pointer crosses the gap above the badge. */
  pointer-events:none;
}
.badge-hint strong{ color:var(--ink); font-weight:600; }

.has-hint:hover .badge-hint,
.has-hint:focus .badge-hint,
.has-hint:focus-within .badge-hint{
  opacity:1;
  visibility:visible;
}
.has-hint:focus-visible{ outline:2px solid var(--line); outline-offset:3px; }

.badge-countries{
  display:flex;
  flex-direction:column;
  gap:4px;
}
.badge-country{
  display:flex;
  align-items:center;
  gap:7px;
  color:var(--ink);
}
.badge-country img{ border-radius:2px; flex-shrink:0; }

/* A hovered tile is lifted by a transform, which puts it in its own stacking
   context; without this the panel would slide under the following tiles. */
.tile:hover, .tile:focus-within{ z-index:10; }

/* ---------------------------------------------------------------------------
 * Trusted countries
 *
 * The box reuses .status-card from the start page - same frame, same dot, same
 * pulse - and only adds what this page shows on top: the flag of the current
 * origin at twice the size of the one in the status row, the network name
 * below it, and the prepared mail where there is something to ask for.
 *
 * The list of countries sits outside the box, centred, one per line.
 * ------------------------------------------------------------------------- */
.origin-wrap{
  max-width:var(--prose-max);
  margin:0 auto;
  padding:0 24px 8px;
}

.origin-body{
  margin-top:22px;
}
/* 40x30 against the 20x15 of the status row: twice the flag, so the page says
   at a glance where the request comes from. */
.origin-flag{
  display:block;
  margin:0 auto 12px;
  border-radius:3px;
  box-shadow:var(--shadow-mark);
}
.origin-network{
  font-family:Georgia,serif;
  font-size:22px;
}
.origin-country{
  margin-top:4px;
  font-size:13.5px;
  color:var(--ink-soft);
}

.origin-action{
  margin:22px 0 0;
}
.origin-button{
  display:inline-block;
  padding:9px 18px;
  border:1px solid var(--pine);
  border-radius:999px;
  color:var(--pine);
  font-size:14px;
  text-decoration:none;
  transition:background .15s ease, color .15s ease;
}
.origin-button:hover, .origin-button:focus-visible{
  background:var(--pine);
  color:var(--paper-raised);
}
.origin-hint{
  display:block;
  margin-top:8px;
  font-size:12.5px;
  color:var(--ink-soft);
}

/* The line that says what the list below is. Same face and size as a heading
   in a guide, so a heading reads the same wherever it stands. */
.country-heading{
  font-family:Georgia,serif;
  font-size:24px;
  font-weight:700;
  max-width:var(--prose-max);
  margin:44px auto 0;
  padding:0 24px;
  text-align:center;
  text-shadow:var(--text-lift);
}

.country-list{
  list-style:none;
  max-width:var(--prose-max);
  margin:20px auto 0;
  padding:0 24px;
  text-align:center;
}
.country-list li{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  padding:10px 0;
  border-bottom:1px solid var(--line);
}
.country-list li:last-child{ border-bottom:0; }
.country-flag{
  border-radius:2px;
  flex-shrink:0;
}
.country-name{
  font-family:Georgia,serif;
  font-size:16px;
}
.country-code{
  font-size:12px;
  letter-spacing:.06em;
  color:var(--ink-soft);
}

/* No country released. It is a state of its own and says so, rather than
   leaving a heading with nothing under it. */
.country-empty{
  max-width:var(--prose-max);
  margin:20px auto 0;
  padding:0 24px;
  text-align:center;
  font-size:15px;
  line-height:1.65;
}

.country-note{
  max-width:var(--prose-max);
  margin:28px auto 0;
  padding:0 24px;
  text-align:center;
  font-size:13.5px;
  color:var(--ink-soft);
}
.country-note a{ color:var(--pine); }


/* ---------------------------------------------------------------------------
 * The chooser repeated above a page it leads to
 *
 * A guide below /vpn carries every choice that led to it, one row per level
 * and the topmost first, so somebody can change the system or the way without
 * walking back up through the pages in between.
 *
 * Smaller than on the chooser page itself: here it is a way to switch, not the
 * choice somebody came to make, and it sits above the text rather than being
 * the point of the page.
 * ------------------------------------------------------------------------- */
.switcher{
  margin-top:0;
  margin-bottom:28px;
}
.tiles-switch .tile{
  width:150px;
  padding:14px 12px 12px;
}
.tiles-switch .tile .mark{
  width:34px;
  height:34px;
  margin-bottom:8px;
  font-size:13px;
}
.tiles-switch .tile .mark[data-mark-len="3"]{ font-size:11px; }
.tiles-switch .tile .mark[data-mark-len="4"]{ font-size:10px; }
.tiles-switch .tile .name{ font-size:13.5px; }

/* ---------------------------------------------------------------------------
 * A chooser whose entries need a sentence
 *
 * Some destinations cannot be told apart by their name. The three BrowserCheck
 * stages are the same page three times and differ only in the way there, so
 * the sentence explaining that is the tile rather than a footnote under it -
 * and at the width of a start page tile it turns into six hyphenated lines.
 *
 * Every entry of the row grows by the same amount. The size of the containers
 * may deviate from the start page, a single tile within a row may not
 * (service-pages.md 1.4) - that was the featured tile, and it is gone.
 *
 * The width is two normal tiles plus the gap between them, so a wide row still
 * lines up with the grid the start page sets.
 * ------------------------------------------------------------------------- */
.tiles-wide .tile{
  width:362px;
  padding:28px 24px 26px;
}
.tiles-wide .tile .mark{
  width:60px;
  height:60px;
  margin-bottom:16px;
  font-size:22px;
}
.tiles-wide .tile .mark[data-mark-len="3"]{ font-size:18px; }
.tiles-wide .tile .mark-symbol svg{ width:56%; height:56%; }
.tiles-wide .tile .mark[data-mark-len="4"]{ font-size:15px; }
.tiles-wide .tile .name{
  font-size:20px;
  margin-bottom:8px;
}
.tiles-wide .tile .desc{ font-size:13.5px; }
/* Below this the fixed width would push the page sideways. A full width tile
   is not the phone layout this wants in the end, it is the guard that keeps
   the page from scrolling horizontally until that layout is built. */
@media (max-width:420px){
  .tiles-wide .tile{ width:100%; }
}

/* The page somebody is already reading. It keeps its place in the row rather
   than disappearing - a gap reads as a missing entry - but it stops looking
   like somewhere to go. */
.tile-current{
  border-color:var(--accent,var(--line));
  background:var(--accent-soft,var(--paper-raised));
  cursor:default;
}
.tile-current:hover{
  transform:none;
  box-shadow:var(--shadow-rest);
}


/* ---------------------------------------------------------------------------
 * The text belonging to a row of tiles
 *
 * Every chooser explains the choice below it. That is worth reading once and
 * in the way once it has been, so it sits in a fold - open by default, and
 * closed for thirty days once somebody closes it. A details element rather
 * than a script: it opens and closes without JavaScript, and the server
 * decides from the cookie whether it starts open, so the page does not
 * rearrange itself after loading.
 * ------------------------------------------------------------------------- */
.intro{
  max-width:var(--prose-max);
  margin:0 auto 18px;
  padding:0 24px;
}
.intro > summary{
  display:flex;
  align-items:center;
  gap:8px;
  cursor:pointer;
  list-style:none;
  font-size:12.5px;
  letter-spacing:.14em;
  text-transform:uppercase;
  font-weight:700;
  color:var(--ink-soft);
  padding:6px 0;
  transition:color .15s ease;
}
.intro > summary::-webkit-details-marker{ display:none; }
.intro > summary:hover{ color:var(--ink); }
/* The marker is drawn rather than taken from the browser, because the browsers
   disagree on the shape and the ones that agree still disagree on the size. */
.intro > summary::before{
  content:"";
  width:0;height:0;
  border-left:5px solid currentColor;
  border-top:4px solid transparent;
  border-bottom:4px solid transparent;
  transition:transform .15s ease;
  flex-shrink:0;
}
.intro[open] > summary::before{ transform:rotate(90deg); }
@media (prefers-reduced-motion: reduce){
  .intro > summary::before{ transition:none; }
}
.intro > summary::after{
  content:"";
  flex:1;
  height:1px;
  background:var(--line);
}
.intro .prose{
  margin-bottom:6px;
}


/* ---------------------------------------------------------------------------
 * The way one level up, and the eyebrow as the way home
 *
 * The arrow sits level with the title, at the left edge of a column as wide as
 * running text. It belongs to the page, not to the corner of the window.
 *
 * Which column depends on the page, not on the stylesheet. A chooser page has
 * its tiles centred in a narrow block, so an arrow at the outer edge would
 * hang alone in 400 pixels of nothing. The admin tools fill the full width
 * with headings that run edge to edge, and there the narrow anchor lands in
 * the middle of nowhere. The narrow column is the default and hero-line-wide
 * is the exception, because most pages are prose.
 *
 * It is centred on the title rather than offset by a measured number of
 * pixels, so it keeps its place when the heading grows with the viewport.
 * ------------------------------------------------------------------------ */
.hero-line{
  position:relative;
  max-width:var(--prose-max);
  margin:0 auto;
}
/* Pages whose content runs the full width: the start page and the admin tools.
   Their headings and tile rows reach the outer edge, so the arrow does too. */
.hero-line-wide{ max-width:var(--wrap-max); }
.hero-line-wide .uplink{ left:0; }
.uplink{
  position:absolute;
  /* Level with the left border of a text card, which sits 24px inside its own
     container. */
  left:24px;
  top:50%;
  transform:translateY(-50%);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  border-radius:50%;
  border:1px solid var(--line);
  background:var(--paper-raised);
  color:var(--ink-soft);
  box-shadow:var(--shadow-rest);
  transition:transform .15s ease, color .15s ease, border-color .15s ease;
}
.uplink svg{ width:18px; height:18px; }
.uplink:hover, .uplink:focus-visible{
  color:var(--ink);
  border-color:var(--ink-soft);
  transform:translateY(-50%) translateX(-3px);
  outline:none;
}
/* Narrow screens have no room beside the heading, so the arrow steps above it
   instead of overlapping the text. */
@media (max-width:700px){
  .uplink{
    position:static;
    transform:none;
    margin-bottom:10px;
  }
  .uplink:hover, .uplink:focus-visible{ transform:translateX(-3px); }
  .hero-line{ display:flex; flex-direction:column; align-items:center; }
}
/* The eyebrow leads home. It keeps its own colour and weight, so nothing about
   the header changes visually until somebody points at it. */
.eyebrow a{
  color:inherit;
  text-decoration:none;
}
.eyebrow a:hover, .eyebrow a:focus-visible{
  text-decoration:underline;
  text-underline-offset:3px;
  outline:none;
}
