/*
Theme Name:  Downtown Arnprior
Description: The block theme for the downtown Arnprior business hub. Every
             template is a thin shell around one PHP pattern, because the
             eighteen page designs are bespoke and a pattern is a PHP file.
             See docs/decisions/0002.
Version:     0.16.0
Author:      Kingsbury Creative
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.2
Text Domain: dta
*/

/* ----------------------------------------------------------------
   THE FOUR STEPS

   620   two columns
   800   tablet
   1000  desktop

   And two that are not free to move:

   1024  the nav drawer, and system.js watches this exact number with
         matchMedia. Change one without the other and the body stays
         scroll-locked when the window grows.
   1180  the nav gap, and it is contentSize in theme.json.

   Nothing else. There were nineteen, because eighteen page designs
   each solved "wide enough for two columns" against their own ruler:
   600, 620 and 640 all meant the same thing, and so did 860, 900,
   940, 960 and 980.

   The numbers are written down in theme.json under custom.step as
   well, which is where a person looks for a design value. They are
   repeated here because @media cannot read a custom property: the
   query is evaluated before the cascade, so var() in a media
   condition is not a thing. Two copies, and this comment is the
   reason they have to be kept in step by hand.
   ----------------------------------------------------------------- */

/* ----------------------------------------------------------------
   TOKENS
   theme.json is the design system. Every colour, type size and
   spacing value lives there and nowhere else. This block only gives
   them the short names the design was written against, so the CSS
   ported from design/system.css reads as it was written.

   If you are about to type a hex into this file, put it in
   theme.json instead and alias it here.
   ---------------------------------------------------------------- */
:root{
  --paper:var(--wp--preset--color--paper);
  --paper-2:var(--wp--preset--color--paper-2);
  --ink:var(--wp--preset--color--ink);
  --ink-soft:var(--wp--preset--color--ink-soft);
  --yellow:var(--wp--preset--color--yellow);
  --card:var(--wp--preset--color--card);
  --danger:var(--wp--preset--color--danger);
  /* Open, closing soon and closed are green, yellow and grey. The colour is
     never the only carrier: the badge says the words as well. */
  --open:var(--wp--preset--color--open);

  --line:var(--wp--custom--line);

  /* The navy bands are the header, the drawer, the footer, the join
     board and every inverted section. They keep the same palette in
     light, dark and high contrast on purpose: the signboard does not
     change colour when the page does. */
  --navy:var(--wp--preset--color--navy);
  --on-navy:var(--wp--preset--color--on-navy);
  --on-navy-line:var(--wp--custom--on-navy-line);
  --photo-ink:var(--wp--preset--color--photo-ink);

  --disp:var(--wp--preset--font-family--display);
  --body:var(--wp--preset--font-family--body);

  --t-s:var(--wp--preset--font-size--s);
  --t-b:var(--wp--preset--font-size--b);
  --t-m:var(--wp--preset--font-size--m);
  --t-l:var(--wp--preset--font-size--l);
  --t-xl:var(--wp--preset--font-size--xl);

  --gut:var(--wp--preset--spacing--gut);
  --band:var(--wp--preset--spacing--band);

  /* the space under a heading, scaled to the same vw term the type itself
     uses. A fixed rem here is why the gap under a name reads fine on a
     phone and broken on a desktop: the heading grows, the gap does not. */
  --sp-3xs:var(--wp--custom--space--tight);
  --sp-2xs:var(--wp--custom--space--snug);
  --sp-xs:var(--wp--custom--space--open);
  --sp-s:var(--wp--custom--space--wide);

  --hdr-h:var(--wp--custom--header-height);

  /* Where a sticky sub-bar parks. The header is fixed and hides itself on
     the way down the page, so a bar parked at --hdr-h leaves an empty 62px
     strip with the page scrolling through it. system.js puts .hdr-away on
     the html element whenever the header is out, and this drops to zero. */
  --stick-top:var(--hdr-h);

  /* the layer scale. Nothing on this site sets a z-index that is not
     one of these five. Leaflet is why: it hard-codes up to 800 on its
     own panes, which beat a header at 50. */
  --z-map:var(--wp--custom--layer--map);
  --z-sticky:var(--wp--custom--layer--sticky);
  --z-hdr:var(--wp--custom--layer--header);
  --z-nav:var(--wp--custom--layer--nav);
  --z-skip:var(--wp--custom--layer--skip);
}

/* derive the hairline from the ink so a theme only sets one colour */
@supports (color:color-mix(in srgb,red 50%,white)){
  :root{--line:color-mix(in srgb,var(--ink) 17%,transparent)}
}

/* the display-options bar sets these attributes; the head script restores
   them from localStorage before first paint so nothing flashes */
html[data-fs="1"]{font-size:112.5%}
html[data-fs="2"]{font-size:125%}
/* The three other theme states. Their palettes live in theme.json under
   settings.custom, same as every other colour on the site. */
:root[data-thr="dark"]{
  --paper:var(--wp--custom--dark--paper);
  --paper-2:var(--wp--custom--dark--paper-2);
  --ink:var(--wp--custom--dark--ink);
  --ink-soft:var(--wp--custom--dark--ink-soft);
  --line:var(--wp--custom--dark--line);
  --card:var(--wp--custom--dark--card);
  /* The light danger red is #a3271b and it measures 1.97:1 against the dark
     card, so a field marked wrong in dark mode was marked in a colour nobody
     could see. Same failure as the focus ring, found the same way. */
  --danger:var(--wp--custom--dark--danger);
}
:root[data-hc="1"]{
  --paper:var(--wp--custom--contrast--paper);
  --paper-2:var(--wp--custom--contrast--paper-2);
  --ink:var(--wp--custom--contrast--ink);
  --ink-soft:var(--wp--custom--contrast--ink-soft);
  --line:var(--wp--custom--contrast--line);
  --card:var(--wp--custom--contrast--card);
}
:root[data-thr="dark"][data-hc="1"]{
  --paper:var(--wp--custom--dark-contrast--paper);
  --paper-2:var(--wp--custom--dark-contrast--paper-2);
  --ink:var(--wp--custom--dark-contrast--ink);
  --ink-soft:var(--wp--custom--dark-contrast--ink-soft);
  --line:var(--wp--custom--dark-contrast--line);
  --card:var(--wp--custom--dark-contrast--card);
  --danger:var(--wp--custom--dark-contrast--danger);
}
@supports (color:color-mix(in srgb,red 50%,white)){
  :root[data-thr="dark"]{--line:color-mix(in srgb,var(--ink) 18%,transparent)}
  :root[data-hc="1"],:root[data-thr="dark"][data-hc="1"]{
    --line:color-mix(in srgb,var(--ink) 40%,transparent)}
}

/* ----------------------------------------------------------------
   BASE
   ---------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--body);font-size:var(--t-b);line-height:1.65;
  overflow-x:clip;
}
img{max-width:100%;display:block}
a{color:inherit}
/* A link that leaves this site says so and opens in its own tab, so the page
   somebody was reading is still there when they come back. The hook is the
   target attribute and not the href: matching the href means writing the
   site's domain into this file, and it is a different domain on a laptop than
   it is on the real one.

   Drawn as a mask rather than a character or a coloured image, so it takes
   whatever colour the link is. That matters in three places at once: the navy
   footer, dark mode, and both contrast modes. */
:root{--icon-out:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6'/%3E%3Cpath d='M20 4 11 13'/%3E%3Cpath d='M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5'/%3E%3C/svg%3E")}
a[target="_blank"]::after{content:"";display:inline-block;width:.72em;height:.72em;
  margin-left:.34em;vertical-align:-.02em;background:currentColor;
  -webkit-mask:var(--icon-out) center/contain no-repeat;
  mask:var(--icon-out) center/contain no-repeat}
h1,h2,h3{margin:0;font-family:var(--disp);font-weight:800;line-height:1.06;letter-spacing:-.01em}
/* balance keeps a two-line headline from leaving one orphan word.
   Ignored where unsupported, which costs nothing. */
h1,h2,h3,.lede,.kick{text-wrap:balance}
p{margin:0 0 1em;text-wrap:pretty}
::selection{background:var(--yellow);color:var(--ink)}

/* The focus ring, and it is two rings on purpose.

   One colour cannot do this. The ring has to read on paper, on the navy
   bands, over a photograph and on a yellow button, and the brightness
   windows those demand do not overlap: navy needs a light ring and
   yellow needs a dark one. There is no single value that clears 3:1
   against both.

   This rule used to be one ink outline. --ink and --navy are the same
   hex in light mode, so a keyboard user tabbing into the footer got an
   outline at 1:1 against the band behind it, which is to say nothing at
   all. Measured on /contact/, not noticed by looking.

   So: ink outside, paper inside, the inner ring filling the gap the
   offset opens. Those two are opposite ends of the palette in all four
   theme states, so whichever one loses its contrast against the thing
   behind it, the other one has it. Same trick the browser's own default
   ring uses. */
:focus-visible{
  outline:3px solid var(--ink);
  outline-offset:3px;
  box-shadow:0 0 0 3px var(--paper);
}

/* anything an in-page link points at clears the sticky header */
:target,[id]{scroll-margin-top:calc(var(--hdr-h) + 1rem)}

.wrap{width:min(100% - (var(--gut)*2),1160px);margin-inline:auto}
.skip{position:absolute;left:-999px}
.skip:focus{left:.5rem;top:.5rem;z-index:var(--z-skip);background:var(--ink);color:var(--paper);
  padding:0 1.1rem;min-height:44px;display:inline-flex;align-items:center}

/* small caps label, used sparingly */
.kick{
  font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.12em;color:var(--ink-soft);
}

/* ----------------------------------------------------------------
   DISPLAY OPTIONS : text size, contrast, colours
   ---------------------------------------------------------------- */
/* This started as six pills in a band above the header, which put roughly a
   hundred pixels of chrome before any of the words on every page. Then it was
   one button in that band, which is a whole strip across the site for one
   control and looked it.

   It is a button in the header now, beside the menu, and the panel drops out
   of the header rather than pushing the page down. The band is gone.

   The button says Aa. It was a faders icon and it did not survive being 18px
   on a navy ground: three tracks with knobs is a shape you decipher, and the
   people most likely to want this button are the ones least able to do that
   at that size. Two letters in the display face read at a glance and say the
   thing the panel mostly does. */
.dispbtn{
  background:none;color:var(--on-navy);border:1px solid #eef1ef55;border-radius:4px;
  width:44px;height:44px;flex:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .15s,color .15s,border-color .15s;
}
.dispbtn-aa{font-family:var(--disp);font-weight:800;font-size:1.02rem;line-height:1;
  letter-spacing:-.01em}
/* The on-navy fill. Shared with the drawer's close button and the ghost
   button: everything drawn transparent on navy fills the same way. Was
   three identical blocks. */
.dispbtn:hover,.dispbtn[aria-expanded="true"],.navx:hover,.ghost:hover{
  background:var(--on-navy);color:var(--navy);border-color:var(--on-navy)}

/* The panel hangs off the header, which is sticky and therefore already a
   containing block, so this needs no wrapper of its own. The insets repeat
   what .wrap does, because the panel has to line up with the page's right
   edge and not the window's. */
.disp{
  display:none;position:absolute;top:100%;z-index:var(--z-hdr);
  left:max(var(--gut),calc((100% - 1160px) / 2));
  right:max(var(--gut),calc((100% - 1160px) / 2));
  background:var(--card);color:var(--ink);
  border:1px solid var(--line);border-top:0;border-radius:0 0 4px 4px;
  padding:.85rem;box-shadow:0 12px 26px #16283e2e;
}
.disp.open{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .6rem}
/* On a phone the pills wrap, and a label that wraps with them ends up in the
   middle of a row belonging to the group above it. Each label takes its own
   line, so the panel reads as three labelled groups rather than one bag. */
.disp b{font-weight:700;font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;
  color:var(--ink-soft);flex-basis:100%}
/* wide enough for the pills to sit on one line, so the panel stops spanning
   the page and becomes what it looks like: a drop-down under its button */
@media (min-width:800px){
  .disp{left:auto}
  .disp b{flex-basis:auto}
}
/* .abtn is one of the pill family. Its base, sizes, hover and pressed
   fill all live under BUTTONS AND PILLS below. */

/* ----------------------------------------------------------------
   HEADER : painted signboard. Navy stays navy in every theme.
   ---------------------------------------------------------------- */
/* Fixed, and it slides out of the way going down the page and comes back the
   moment you go up. Rob's call, taking Sembr's marketing nav as the shape.

   Fixed rather than sticky, and that is the fix as much as the behaviour:
   sticky was declared here and did nothing. Scrolled with a real wheel, the
   header left the top of the screen on every page of this site. Fixed cannot
   be quietly defeated by an ancestor the way sticky can.

   The transform is what moves it, not top, so it is one composited property
   and the paint does not thrash. Reduced motion gets a header that never
   hides at all rather than one that jumps. */
.hdr{
  position:fixed;top:0;left:0;right:0;z-index:var(--z-hdr);
  background:var(--navy);color:var(--on-navy);border-bottom:2px solid var(--yellow);
  transform:translateY(0);
  transition:transform 360ms cubic-bezier(.4,0,.2,1);
}
.hdr.is-hidden{transform:translateY(-100%)}
@media (prefers-reduced-motion:reduce){
  .hdr{transition:none}
  .hdr.is-hidden{transform:none}
}
/* Everything that parks under the header has to travel with it. The class
   goes on the html element rather than the header so a sticky bar four
   sections down the page can see it. Same 360ms and same curve, so the two
   move as one thing instead of one chasing the other. */
:root.hdr-away{--stick-top:0px}
.ctl,.filt,.rail,.reads,.prev,.grp-lab,.mon-lab{
  transition:top 360ms cubic-bezier(.4,0,.2,1);
}
@media (prefers-reduced-motion:reduce){
  :root.hdr-away{--stick-top:var(--hdr-h)}
  .ctl,.filt,.rail,.reads,.prev,.grp-lab,.mon-lab{transition:none}
}
/* The header is out of the flow now, so the page has to start below it. Plus
   2px, because --hdr-h is the min-height of the row inside and the yellow
   rule sits outside that: measured, the header occupies 62px and a 60px
   spacer left the weather band's first two pixels under it forever. */
.wp-site-blocks{padding-top:calc(var(--hdr-h) + 2px)}
.hdr-in{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:var(--hdr-h)}
/* the nav, the display-options button and the menu button travel together at
   the right-hand end, so .hdr-in stays two children and space-between works */
.hdr-end{display:flex;align-items:center;gap:.6rem}
@media (min-width:1024px){.hdr-end{gap:1.45rem}}
.mark{font-family:var(--disp);font-weight:800;font-size:1.12rem;line-height:1.05;
  text-decoration:none;display:flex;align-items:center;min-height:44px}
.mark span{color:var(--yellow)}

/* the menu button, and the close button that replaces it when open */
.navbtn{
  font-family:var(--body);font-weight:700;font-size:var(--t-s);letter-spacing:.06em;
  text-transform:uppercase;background:none;color:var(--on-navy);border:1px solid #eef1ef55;
  border-radius:4px;padding:0 1.15rem;min-height:44px;cursor:pointer;
  display:inline-flex;align-items:center;gap:.6rem;
}
.navbtn svg{width:15px;height:15px;stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round}

/* ---- the drawer ----
   Covers the whole screen including the header, so there is never a
   half-lit page behind it. Items sit at the bottom left, which is
   where a thumb already is on a phone. */
/* display:none can't transition, so the drawer stays display:flex always
   and hides through transform/visibility instead -- fixed positioning
   takes it out of flow either way, so an always-present drawer costs
   nothing when it is not open. No opacity: a fade is exactly as
   see-through as it sounds for the length of the transition, and this
   drawer already covers the whole screen specifically so nothing shows
   through it -- a fade would work against the one thing it is for.
   Transform only, so it is opaque throughout and reads as a physical
   drawer sliding down rather than a thing materializing. visibility flips
   at the end of the close transition (the 0s duration, .28s delay) rather
   than with it, so a hidden drawer still cannot be tabbed into or read by
   a screen reader one frame after it looks gone. Opening reverses the
   delay to zero, so it becomes interactive the instant it starts moving. */
.nav{
  display:flex;flex-direction:column;justify-content:flex-end;
  position:fixed;inset:0;z-index:var(--z-nav);
  background:var(--navy);color:var(--on-navy);
  padding:var(--gut);
  padding-bottom:max(var(--gut),env(safe-area-inset-bottom));
  height:100vh; height:100dvh;          /* dvh second: old browsers keep vh */
  overflow:auto;overscroll-behavior:contain;
  visibility:hidden;pointer-events:none;transform:translateY(-100%);
  transition:transform .32s cubic-bezier(.4,0,.2,1),visibility 0s linear .32s;
}
.nav.open{
  visibility:visible;pointer-events:auto;transform:translateY(0);
  transition:transform .32s cubic-bezier(.4,0,.2,1),visibility 0s linear 0s;
}
@media (prefers-reduced-motion:reduce){.nav{transition:visibility 0s linear .01s;transform:none}}
.nav::before{                       /* the yellow rule the header had */
  content:"";position:absolute;inset:0 0 auto;height:2px;background:var(--yellow);
}
/* Room between the items, not just around the words. A drawer on a phone is
   thumbed at speed and the rules were 60px apart, which is close enough that
   the wrong one gets hit. */
.nav a{
  display:flex;align-items:center;min-height:74px;text-decoration:none;
  font-family:var(--disp);font-weight:700;
  font-size:clamp(1.75rem,8vw,2.6rem);line-height:1.1;
  border-bottom:1px solid var(--on-navy-line);
}
.nav a:first-child{border-top:1px solid var(--on-navy-line)}
.nav a:hover,.nav a:focus-visible{color:var(--yellow)}
.nav a[aria-current]{color:var(--yellow)}
/* close sits top right of the drawer, thumb-reachable and obvious */
.navx{
  position:absolute;top:calc(var(--gut) - .3rem);right:calc(var(--gut) - .3rem);
  width:52px;height:52px;border-radius:50%;
  background:none;border:1px solid #eef1ef55;color:var(--on-navy);cursor:pointer;
  display:none;align-items:center;justify-content:center;
}
.nav.open .navx{display:flex}
.navx svg{width:20px;height:20px;stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round}
/* the hover is the shared on-navy fill, up with .dispbtn */
.nav-foot{margin-top:1.6rem;font-size:var(--t-s);color:#eef1ef9e}

/* Seven items plus the wordmark need more room than five did, so the drawer
   holds on until 1024 rather than 920. Adding the display-options button put
   the row 8px over its own wrap at exactly 1024; tightening the nav's
   tracking took it back under, so this stays at 1024 rather than becoming a
   fifteenth breakpoint. Checked at 1024, 1060, 1100 and up: no overflow and
   no horizontal scroll anywhere. */
@media (min-width:1024px){
  .navbtn,.navx{display:none}
  .nav,.nav.open{display:flex;flex-direction:row;align-items:center;
    position:static;inset:auto;height:auto;
    background:none;padding:0;gap:1.45rem;overflow:visible;z-index:auto;
    visibility:visible;pointer-events:auto;transform:none;transition:none}
  .nav::before{display:none}
  /* .02em, not .04em. Seven uppercase items and a button filled the row, and
     tracking is the cheapest thing in it to give back. Measured, halving it
     returns 17px across the whole nav, not the forty I guessed, which is
     still enough to let the row go back to fitting at 1024. */
  .nav a,.nav a:first-child{border:0;font-family:var(--body);font-weight:700;font-size:var(--t-s);
    letter-spacing:.02em;text-transform:uppercase;min-height:44px;white-space:nowrap}
  /* A real underline rather than a box-shadow along the bottom edge. The
     link's box is 44px tall for the thumb, so an inset shadow drew a thick
     yellow bar down at the bottom of that box with a gap between it and the
     word. This is the same underline the breadcrumbs use on hover, and it
     hugs the text. Not colour alone: colour is not a signal on its own for
     anyone who cannot see it. */
  .nav a[aria-current]{color:inherit;text-decoration:underline;
    text-decoration-color:var(--yellow);text-decoration-thickness:2px;
    text-underline-offset:.42em}
  .nav-foot{display:none}
}
@media (min-width:1180px){.nav,.nav.open{gap:1.9rem}}

/* ----------------------------------------------------------------
   BUTTONS AND PILLS
   ---------------------------------------------------------------- */
.cta{
  display:inline-flex;align-items:center;justify-content:center;min-height:52px;
  font-weight:700;font-size:var(--t-s);letter-spacing:.06em;text-transform:uppercase;
  text-decoration:none;padding:0 1.6rem;background:var(--ink);color:var(--paper);
  border:0;border-radius:6px;margin-top:1.6rem;transition:background .15s;
  font-family:var(--body);cursor:pointer;text-align:center;
}
/* the hover has to come from the ink token, not from a fixed navy.
   A hardcoded #0e1c2e is invisible in dark mode, where the button is
   already light with dark type on it, and it breaks high contrast
   the same way. Mixing toward the paper reads as pressed into the
   page and stays legible in all four themes. The literal is the
   fallback and is correct in the default one. */
.cta:hover{background:#0e1c2e}
.cta:active{background:#0a1524}
@supports (color:color-mix(in srgb,red 50%,white)){
  .cta:hover{background:color-mix(in srgb,var(--ink) 86%,var(--paper))}
  .cta:active{background:color-mix(in srgb,var(--ink) 74%,var(--paper))}
}
.cta.yellow{background:var(--yellow);color:var(--navy)}
.cta.yellow:hover{background:#e5a51f}
.cta.yellow:active{background:#d2960f}
/* the literals above are the fallback. Mixing toward the navy keeps the
   pressed look in all four themes, the same as the ink button does. The
   hero and the statement band used to each declare this again. */
@supports (color:color-mix(in srgb,red 50%,white)){
  .cta.yellow:hover{background:color-mix(in srgb,var(--yellow) 88%,var(--navy))}
  .cta.yellow:active{background:color-mix(in srgb,var(--yellow) 76%,var(--navy))}
}

/* ---- the pill family ----
   One base for every pill on the site: the display options (.abtn),
   the read-more link (.more), the category rows (.cats), the shop
   page's action row (.state .acts a) and the visit map's layer
   toggles (.lbtn). Each site keeps only its own sizes and spacing.
   This was five near-identical bases and six identical ink fills. */
.abtn,.more,.cats a,.cats button,.state .acts a,.lbtn{
  font-family:var(--body);font-weight:700;font-size:var(--t-s);color:var(--ink);
  background:var(--card);border:1px solid var(--line);border-radius:999px;
  text-decoration:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .15s,color .15s,border-color .15s;
}
/* the display options run smaller than the pill's t-s */
.abtn{font-size:.82rem;min-height:44px;min-width:44px;padding:0 .9rem}
/* the two toggles darken their edge on hover and fill when pressed;
   the plain links fill straight away */
.abtn:hover,.lbtn:hover{border-color:var(--ink)}
.abtn[aria-pressed="true"],.lbtn[aria-pressed="true"],
.more:hover,.cats a:hover,.cats button:hover,
.cats [aria-current],.cats [aria-pressed="true"],
.state .acts a:hover{background:var(--ink);border-color:var(--ink);color:var(--paper)}

.more{letter-spacing:.05em;text-transform:uppercase;padding:0 1.25rem;min-height:46px;
  white-space:nowrap}

/* pill link rows: shop categories, filters */
.cats{display:flex;flex-wrap:wrap;gap:.6rem;margin-bottom:1.6rem}
.cats a,.cats button{letter-spacing:.03em;padding:0 1.15rem;min-height:44px}

/* segmented control: two or three exclusive options */
.seg{display:flex;border:1px solid var(--line);border-radius:999px;background:var(--card);overflow:hidden}
.seg button{
  font-family:var(--body);font-weight:700;font-size:var(--t-s);color:var(--ink);
  background:none;border:0;min-height:46px;padding:0 1.05rem;cursor:pointer;white-space:nowrap;
  transition:background .15s,color .15s;
}
.seg button + button{border-left:1px solid var(--line)}
.seg button[aria-pressed="true"]{background:var(--ink);color:var(--paper)}

/* ----------------------------------------------------------------
   SECTIONS
   ---------------------------------------------------------------- */
.band{padding:var(--band) 0}
.hd{display:flex;align-items:flex-end;justify-content:space-between;gap:1.2rem;flex-wrap:wrap;margin-bottom:1.9rem}
.hd h2{font-size:var(--t-l);max-width:20ch}
.hd .kick{display:block;margin-bottom:var(--sp-3xs)}

/* alternate band: notice-board grey */
.on{background:var(--paper-2);border-block:1px solid var(--line)}

/* breadcrumb line above a page title */
.crumb{font-size:var(--t-s);color:var(--ink-soft);padding:.9rem 0 0}
.crumb a{display:inline-flex;align-items:center;min-height:44px;color:var(--ink-soft);text-decoration:none}
.crumb a:hover{color:var(--ink)}
.crumb span[aria-hidden]{padding:0 .45rem}

/* ---- the yellow underline ----
   The one hover on this site: whatever names a place you can go gets
   the 3px yellow rule under it. Every hover underline lives in this
   list and the pages declare none of their own; it was thirteen
   identical blocks. The always-on underlines (.rail a.link, .p-site,
   .gate .aside a, .hrow.now dt) stay at their sites: same rule,
   different trigger, and two of them differ in offset. */
.crumb a:hover,.ev:hover h3,.qa > summary:hover h3,
a.item:hover h3,.item a:hover h3,.tries a:hover b,
.row:hover h3,.door:hover h2,.tn:hover h2,
.eb:hover h3,.shop-offer:hover h3,.kind:hover h3,
.note:hover h3,.dr:hover h2,.names li a:hover{
  text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:3px;text-underline-offset:.2em;
}

/* ----------------------------------------------------------------
   PAGE HEADS

   Nine of these, one per page design, each with its own class and
   its own type scale, all doing the same job: a crumb, a kicker, a
   headline and sometimes a lede. The nine repeated the same three
   rules with the numbers nudged, so changing the crumb meant
   editing nine places and finding out later which one was missed.

   Three grounds, because three of them really are different: paper,
   navy, and a photograph. Everything above the ground is written
   once, here.

   Four of the nine are gone entirely: the shops, news, one notice
   and about pages are the plain head with a modifier. What is left
   on .season, .post, .win, .vhead and .hero is only the part that is
   theirs: the market strip, the date set big, the photograph and its
   scrim, and the home page's taller poster.
   ---------------------------------------------------------------- */
.phead .kick{display:block;margin:var(--sp-3xs) 0}
.phead h1{font-size:clamp(2.4rem,1.7rem + 3.2vw,4.4rem)}
.phead h1 em{font-style:normal;color:var(--ink-soft)}
.phead .lede{font-size:var(--t-m);line-height:1.45;max-width:34ch;margin:.9rem 0 0}

/* ---- on paper ----
   The navy and photograph heads put their padding on an inner
   element, because they have a background to bleed and the inner is
   what holds it off the edge. A paper head has no such thing, so the
   padding sits on the head itself. */
.phead-plain{padding:calc(var(--band)*.7) 0 calc(var(--band)*.5)}
.phead-plain .lede{color:var(--ink-soft)}
.phead-tint{background:var(--paper-2);border-bottom:1px solid var(--line)}
.phead-rule{border-bottom:1px solid var(--line)}
/* one notice, at reading measure, with its body starting straight after */
.phead-narrow{width:min(100% - (var(--gut)*2),42rem);margin-inline:auto;padding-bottom:0}
.phead-sm h1{font-size:clamp(2.1rem,1.55rem + 2.6vw,3.5rem);max-width:20ch}

/* ---- on navy ----
   The join head and the members head are this same signboard, so the
   band itself is written once. Their own type lives at their sites. */
.phead-navy,.jhead,.ihead{background:var(--navy);color:var(--on-navy);border-bottom:2px solid var(--yellow)}
.phead-navy .crumb,.phead-navy .crumb a{color:#eef1efb5}
.phead-navy .crumb a:hover{color:#fff}
.phead-navy .kick{color:var(--yellow)}
.phead-navy h1{color:#fff}
@supports (color:color-mix(in srgb,red 50%,white)){
  .phead-navy .crumb,.phead-navy .crumb a{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
}

/* ---- over a photograph ----
   The shadows are not decoration. Six photographs by six people have
   six exposures, and a white headline on a bright sky is the one
   thing a scrim alone cannot promise. */
.phead-photo{position:relative;background:var(--photo-ink);color:var(--on-navy);overflow:clip}
.phead-photo .crumb,.phead-photo .crumb a{color:#eef1efc4}
.phead-photo .crumb a:hover{color:#fff}
.phead-photo .kick{color:var(--yellow);text-shadow:0 1px 4px #101824cc}
.phead-photo h1{color:#fff;text-shadow:0 2px 8px #101824e6,0 1px 2px var(--photo-ink)}
.phead-photo .lede{color:#eef1efe6;text-shadow:0 1px 4px #101824cc}
/* no featured image: the shadows come off, because over flat ink they
   read as a smudge rather than as depth */
.phead-bare .kick,.phead-bare h1,.phead-bare .lede{text-shadow:none}

/* ----------------------------------------------------------------
   DIRECTORY ROWS : the register
   ---------------------------------------------------------------- */

/* ----------------------------------------------------------------
   EVENT ROWS : the notice board
   ---------------------------------------------------------------- */
.ev{
  display:grid;grid-template-columns:auto 1fr;gap:var(--sp-2xs) 1.2rem;align-items:baseline;
  border-top:1px solid var(--line);padding:1.35rem 0;
  text-decoration:none;
}
.ev-date{
  font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1;
  white-space:nowrap;
}
.ev-date small{display:block;font-family:var(--body);font-weight:700;font-size:var(--t-s);
  text-transform:uppercase;letter-spacing:.08em;color:var(--ink-soft);margin-top:var(--sp-2xs)}
.ev h3{font-size:var(--t-m)}
.ev .d{grid-column:2;color:var(--ink-soft);font-size:var(--t-b);margin:0;max-width:58ch}
.ev .flag{grid-column:2;font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.08em;color:var(--ink-soft);justify-self:start}
@media (min-width:800px){.ev{grid-template-columns:8.5rem 1fr}}

/* ----------------------------------------------------------------
   Q & A : native disclosure, no JavaScript
   A <details> is keyboard accessible, findable by browser search in
   modern browsers, and works with JS off. It replaces the old
   always-open block and the hand-rolled toggles.
   ---------------------------------------------------------------- */
.faq{border-top:1px solid var(--line)}
.qa{border-bottom:1px solid var(--line)}
.qa > summary{
  list-style:none;cursor:pointer;display:grid;position:relative;
  grid-template-columns:1fr 2rem;gap:1rem;align-items:start;
  padding:1.25rem 0;min-height:44px;
}
.qa > summary::-webkit-details-marker{display:none}
.qa > summary h3{font-size:var(--t-m);max-width:30ch}
/* The plus that turns into a minus.

   The prototype drew it with a <span class="mk"> inside the summary. That
   does not survive an editor: wpautop wraps a lone span in a <p> and the
   marker drops out of the summary's grid. Drawn from the summary's own
   pseudo-elements instead, so the accordion works from the simplest markup
   anybody could type, which is <summary><h3>Question</h3></summary>. */
.qa > summary::before,.qa > summary::after{
  content:"";position:absolute;right:0;top:50%;width:20px;height:2px;
  background:var(--ink);transform:translateY(-50%);transition:transform .18s ease;
}
.qa > summary::after{transform:translateY(-50%) rotate(90deg)}
.qa[open] > summary::after{transform:translateY(-50%) rotate(0)}
.qa .a{padding:0 0 1.35rem;max-width:62ch}
.qa .a p{margin:0 0 .8em}
.qa .a p:last-child{margin:0}
/* The answer used to sit in a second column on a wide screen, pulled
   level with the question by a negative margin. It cost a dead left
   column, squeezed the answer to about forty characters, and once the
   disclosure got its slide the negative margin was clipped by the
   overflow. The answer now runs under its question at every width,
   which is also what it does on a phone. Give the question more room
   before it wraps and that is the whole difference. */
@media (min-width:1000px){
  .qa > summary h3{max-width:44ch}
}

/* the answer slides rather than snapping. Height cannot be animated
   from 0 to auto without interpolate-size, so the whole thing sits
   behind @supports: browsers without it open instantly, which is
   what they did before, and nothing is unreadable either way. */
@supports (interpolate-size:allow-keywords){
  :root{interpolate-size:allow-keywords}
  .qa::details-content{
    block-size:0;overflow:hidden;
    transition:block-size .3s ease,content-visibility .3s allow-discrete;
  }
  .qa[open]::details-content{block-size:auto}
}

@media (prefers-reduced-motion:reduce){
  /* the marker is drawn on the summary itself now; this rule named the
     .mk span it used to live in, so reduced motion stopped reaching it */
  .qa > summary::before,.qa > summary::after{transition:none}
  .qa::details-content{transition:none}
}

/* ----------------------------------------------------------------
   NEWS ITEMS
   ---------------------------------------------------------------- */
.news{display:grid;gap:1.2rem}
@media (min-width:800px){.news{grid-template-columns:1fr 1fr;gap:2.5rem}}
@media (min-width:1000px){.news{grid-template-columns:repeat(3,1fr)}}
.item{border-top:1px solid var(--line);padding:1.2rem 0 1.35rem}
/* the date label is shared with the pinned notice on the news page */
.item time,.pin-note time{font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.08em;color:var(--ink-soft)}
.item h3{font-size:var(--t-m);margin:.55rem 0 .5rem}
.item p{color:var(--ink-soft);margin:0}
/* the whole card is often the link, so kill the underline on the
   element itself as well as on any anchor inside it */
a.item,.item a{text-decoration:none}

/* ----------------------------------------------------------------
   THE STATEMENT BAND

   Says plainly what something is, and backs it with a short ledger
   of facts. The contact page uses it to say what the group is not,
   because everyone assumes Chamber of Commerce. The home page uses
   it to ask the shops to get listed.

   One band, one function that prints it, dta_statement(). The two
   had drifted to two layouts, two ledgers and two type scales.

   Full bleed, on the photograph ink rather than the navy. The join
   band was inset for a while because it was navy and the footer is
   navy, so the bottom of the home page was fifteen hundred pixels of
   one colour. A different dark solves that without giving up the
   full width.

   It takes a photograph if the page has a featured image and reads
   as a flat band if it does not, which is what both pages do today.
   ---------------------------------------------------------------- */
.statement{position:relative;background:var(--photo-ink);color:var(--on-navy);overflow:clip}
.statement-in{position:relative;padding:var(--band) 0;max-width:44rem}

.statement h2{color:#fff;font-size:var(--t-l);max-width:18ch;text-shadow:0 2px 6px #101824d9}
.statement h2 em{font-style:normal;color:var(--yellow)}
.statement p{color:#eef1efe0;max-width:46ch;margin:1rem 0 0;text-shadow:0 1px 3px #101824cc}
.statement .cta{margin-top:1.6rem}

/* the photograph, and the wash that guarantees a value behind the text */
.statement-bg{position:absolute;inset:0}
.statement-bg img{width:100%;height:100%;object-fit:cover;object-position:center 45%}
.statement-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(82deg,#101824f0 0%,#101824cc 46%,#10182466 78%,#10182422 100%)}
@supports (color:color-mix(in srgb,red,blue)){
  .statement-bg::after{background:linear-gradient(82deg,
    color-mix(in srgb,var(--photo-ink) 94%,transparent) 0%,
    color-mix(in srgb,var(--photo-ink) 80%,transparent) 46%,
    color-mix(in srgb,var(--photo-ink) 40%,transparent) 78%,
    color-mix(in srgb,var(--photo-ink) 13%,transparent) 100%)}
}
/* High contrast drops the photograph rather than dimming it further. A
   picture behind text is the first thing to go when somebody has asked
   for contrast. */
:root[data-hc="1"] .statement-bg img{display:none}
:root[data-hc="1"] .statement-bg::after{background:var(--photo-ink)}
.statement-cr{position:absolute;right:.9rem;bottom:.6rem;font-size:.7rem;color:#eef1ef8c}
/* No featured image: the text drops its shadows, which over flat ink
   read as a smudge rather than as depth. */
.statement-bare .kick,.statement-bare h2,.statement-bare p{text-shadow:none}

/* ---- the ledger ----
   A short list of plain facts under a heading. It was written three times,
   once for the join board, once for the contact page's band and once for
   the detail pages, with three different column widths and the same
   everything else. One list now; the dark bands change two colours. */
.facts{margin:0;border-top:1px solid var(--line)}
.facts .drow{display:grid;grid-template-columns:6.8rem 1fr;border-bottom:1px solid var(--line);align-items:baseline}
@media (min-width:620px){.facts .drow{grid-template-columns:8.5rem 1fr}}
.facts .drow:last-child{border-bottom:0}
.facts dt{font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.08em;padding:.85rem 0}
.facts dd{margin:0;font-size:var(--t-b);padding:.85rem 0}
/* on navy or over a photograph */
.facts-dark{border-top-color:var(--on-navy-line);margin-top:1.8rem}
.facts-dark .drow{border-bottom-color:var(--on-navy-line)}
.facts-dark dt{color:var(--yellow)}
/* a value that is only a link is a tap target, not prose. Give it the
   full 44px without pushing the row open. */
.facts dd > a:only-child{display:inline-flex;align-items:center;min-height:44px;margin:-.7rem 0}

/* a heading that introduces a bordered list needs its own air, or it
   sits on the rule. Measured: this was at -1px before. */
.listhead{font-size:var(--t-m);margin:0 0 .95rem}

/* ----------------------------------------------------------------
   THE YELLOW RULE : two widths, and only two
   A short note beside the text gets 4px. A block that carries its
   own headline gets 6px, because a hairline beside 3rem type reads
   as an accident. Four separate widths had grown across the pages
   for the same three jobs; these are the ones that survived.
   ---------------------------------------------------------------- */

/* a small aside: a caveat, a "we are still checking this" */
.sidenote{
  font-size:var(--t-s);color:var(--ink-soft);
  border-left:4px solid var(--yellow);
  padding:.35rem 0 .35rem 1.05rem;margin:1.5rem 0 0;max-width:58ch;
}
.sidenote p{margin:0 0 .55em}
.sidenote p:last-child{margin:0}

/* a tinted panel that summarises what is under it */
.panel{
  background:var(--paper-2);border-left:4px solid var(--yellow);
  padding:1.3rem clamp(1.15rem,4vw,1.5rem) 1.4rem;margin:2rem 0 2.4rem;
}

/* a block whose own headline is the point */
.feature-rule{border-left:6px solid var(--yellow);padding-left:clamp(1.1rem,3vw,2.2rem)}

/* ----------------------------------------------------------------
   THE LOGO MARK
   A business's sign or logo, wherever it appears on a public page.
   One box, one set of rules, so eighteen logos of eighteen different
   shapes and qualities still line up. Contained, never cropped, on a
   neutral tile so a transparent PNG and a white JPG look alike.
   Falls back to the first letter of the name when there is no file,
   which there often will not be.
   ---------------------------------------------------------------- */
.logo-mark{
  width:var(--mark-size,56px);height:var(--mark-size,56px);flex:none;
  border:1px solid var(--line);border-radius:4px;background:var(--card);
  display:grid;place-items:center;overflow:hidden;
  font-family:var(--disp);font-weight:800;color:var(--ink-soft);
  font-size:calc(var(--mark-size,56px) * .5);line-height:1;
}
.logo-mark img{width:100%;height:100%;object-fit:contain;padding:6px}
.logo-mark.lg{--mark-size:clamp(72px,11vw,104px)}
/* over the photograph the tile has to stay light or a dark logo
   disappears into it */
.win .logo-mark{border-color:#eef1ef4a;background:var(--on-navy)}

/* ----------------------------------------------------------------
   FORMS : big targets, plain labels, one column
   ---------------------------------------------------------------- */
/* wp_login_form prints its own p.login-username and p.login-password
   boxes and nothing can put .field or .in on them from outside, so
   core's class names ride along here rather than getting a wholesale
   copy of these rules down at the members gate. */
.field,.gate .login-username,.gate .login-password{display:grid;gap:.4rem;margin:0 0 1.25rem}
/* A display value silently beats the hidden attribute, and .field sets one.
   Without this line, hiding a field with hidden does nothing and says nothing.
   Fifth time on this project. */
.field[hidden]{display:none}
/* The small-caps label. Also the shop page's hours ledger, the join
   form's day column and the forecast drawer's day names, which are
   the same label on other ledgers: one rule, not five. */
.field label,.field .lab,.gate .login-username label,.gate .login-password label,
.hrow dt,.wday,.nowfc-when{font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.08em}
.field .help{font-size:var(--t-s);color:var(--ink-soft)}
.in,.gate .login-username input,.gate .login-password input{
  font-family:var(--body);font-size:var(--t-b);color:var(--ink);
  background:var(--card);border:1px solid var(--ink-soft);border-radius:4px;
  padding:.6rem .9rem;min-height:52px;width:100%;
}
textarea.in{min-height:9rem;line-height:1.55;resize:vertical}
/* grows with what is typed, where the browser can do it */
@supports (field-sizing:content){
  textarea.in{field-sizing:content;max-height:26rem}
}
select.in{cursor:pointer}
.in::placeholder{color:var(--ink-soft);opacity:.75}
.in:focus-visible{border-color:var(--ink)}

/* ----------------------------------------------------------------
   THE MAP : Leaflet, theme-aware tiles, pulsing pins
   ---------------------------------------------------------------- */
/* isolation opens a stacking context without needing a position, so
   Leaflet's hard-coded panes (400) and controls (800) are measured
   against each other inside here and never against the header. The
   positioned z-index is the fallback for anything without isolation. */
.lmap{
  height:clamp(340px,44vw,500px);border-radius:4px;background:var(--paper-2);
  position:relative;z-index:var(--z-map);isolation:isolate;
}
.lmap .leaflet-container{font-family:var(--body)}
.pin{display:block;width:15px;height:15px;background:var(--yellow);
  border:2px solid var(--ink);border-radius:50%;position:relative}
.pin .ring{position:absolute;inset:-7px;border:2px solid var(--yellow);
  border-radius:50%;animation:ping 2.8s ease-out infinite;opacity:0}
@keyframes ping{0%{transform:scale(.5);opacity:.9}70%{transform:scale(1.15);opacity:0}100%{opacity:0}}
.leaflet-popup-content-wrapper{border-radius:4px;color:var(--navy)}
.leaflet-popup-content b{font-family:var(--disp);font-size:1.05rem}
.leaflet-popup-content span{color:#43536a;font-size:.85rem;display:block;margin-top:.15rem}
.leaflet-popup-content .pop-name{display:inline-block;font-family:var(--disp);font-weight:800;
  font-size:1.05rem;color:var(--navy);text-decoration:underline;text-decoration-color:#f7b32b;
  text-decoration-thickness:3px;text-underline-offset:.22em;padding:.1rem 0 .15rem}
.leaflet-popup-content .pop-name:hover{text-decoration-color:var(--navy)}
.map-cap{display:flex;justify-content:space-between;gap:.4rem 1rem;flex-wrap:wrap;
  border-top:1px solid var(--line);padding:.65rem 0;font-size:var(--t-s);color:var(--ink-soft)}
.map-cap b{color:var(--ink)}
/* the OSM and CARTO credit, moved off the map and into the caption.
   Required by ODbL and by CARTO's terms; it is not decoration. */
.map-credline,.map-dir{margin:.5rem 0 1rem}
.map-cred{font-size:.78rem;color:var(--ink-soft);opacity:.85}
.map-cred a{color:inherit;text-decoration:underline;text-underline-offset:.15em}
.map-cred a:hover{color:var(--ink)}

/* album mount: a print under four flat black corners. The one licensed
   piece of skeuomorphism; do not re-embellish the corners. */
.mount{position:relative;display:inline-block;line-height:0}
.mount img{display:block;max-width:100%;width:auto;height:auto;
  border:10px solid #f8f8f4;box-shadow:0 3px 14px #0a0f1440}
.pc{position:absolute;width:clamp(30px,3.8vw,44px);height:clamp(30px,3.8vw,44px);
  overflow:visible;filter:drop-shadow(1px 1px 2px #0a0f1440)}
.pc path{fill:#12161d}
:root[data-thr="dark"] .pc path{fill:#0b0e13}
.pc.tl{top:-6px;left:-6px}
.pc.tr{top:-6px;right:-6px;transform:rotate(90deg)}
.pc.br{bottom:-6px;right:-6px;transform:rotate(180deg)}
.pc.bl{bottom:-6px;left:-6px;transform:rotate(270deg)}

/* carousel / pager arrows */
.arrb{background:none;border:0;cursor:pointer;padding:0;color:var(--ink);
  font-size:1.7rem;line-height:1;min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;transition:transform .15s}
.arrb:hover{transform:translateX(2px)}
.arrb.prev:hover{transform:translateX(-2px)}
.arrb.pause{font-size:var(--t-s);font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  min-width:auto;padding-inline:.4rem;margin-left:auto}
.arrb.pause:hover{transform:none}

/* ----------------------------------------------------------------
   FOOTER
   ---------------------------------------------------------------- */
.ft{background:var(--navy);color:var(--on-navy);padding:var(--band) 0 2rem;border-top:1px solid var(--on-navy-line)}
.ft-grid{display:grid;gap:2.2rem}
@media (min-width:1000px){.ft-grid{grid-template-columns:1.3fr 1fr 1fr}}
.ft h2{font-size:clamp(2.2rem,8vw,4.6rem);line-height:1;margin-bottom:2rem}
.ft h2 span{color:var(--yellow)}
.ft h3{font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.11em;
  color:var(--yellow);margin:0 0 .6rem;font-family:var(--body)}
.ft a{display:flex;align-items:center;min-height:44px;text-decoration:none;color:var(--on-navy)}
.ft a:hover{color:var(--yellow)}
.ft address{font-style:normal;color:#eef1efc9;line-height:1.7}
.ft-note{margin-top:1rem;color:#eef1efc9}
@supports (color:color-mix(in srgb,red 50%,white)){
  .ft address,.ft-note{color:color-mix(in srgb,var(--on-navy) 79%,transparent)}
}
.fine{border-top:1px solid var(--on-navy-line);margin-top:2.4rem;padding-top:1.3rem;
  font-size:var(--t-s);color:#eef1efb0;line-height:1.8}
/* Centred on a desktop only. Rob's call. On a phone these two lines wrap
   to four and centred wrapped text is harder to read than ragged right,
   so the small screen keeps the left edge everything else on the page
   is lined up on. */
@media (min-width:1000px){
  .fine{text-align:center}
  .legal{justify-content:center;text-align:center}
}

/* ---- back to top ----
   Under the legal line, centred, quiet. A link and not a button so it
   works with scripts off, and it is the last thing in the footer because
   that is where somebody who has read to the bottom is. */
.totop{display:flex;width:fit-content;align-items:center;gap:.5rem;
  margin:1.6rem auto 0;min-height:44px;padding:0 1rem;
  font-size:var(--t-s);font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:#eef1efb5;text-decoration:none;border:1px solid var(--on-navy-line);
  border-radius:999px;transition:color .15s,border-color .15s}
.totop:hover,.totop:focus-visible{color:#fff;border-color:#eef1ef6b}
.totop svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
@supports (color:color-mix(in srgb,red 50%,white)){
  .totop{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
}

.legal{display:flex;flex-wrap:wrap;gap:.4rem 2rem;align-items:center;
  border-top:1px solid var(--on-navy-line);margin-top:1.4rem;padding-top:1.1rem;
  font-size:.75rem;color:#eef1efb0}
.legal nav{display:flex;gap:1.6rem}
.legal a{display:inline-flex;align-items:center;min-height:44px;color:#eef1efd8;text-decoration:none}
.legal a:hover{color:var(--yellow)}

/* ----------------------------------------------------------------
   ERROR AND EMPTY PAGES
   One layout, different copy. 404, 403, 500, 503 and no-results all
   use it, so a stranger who hits any of them lands somewhere that
   looks like the site and offers a way out.
   ---------------------------------------------------------------- */
/* The column that pins the thin footer to the bottom goes on
   .wp-site-blocks and not on the body. A block theme wraps the whole
   template in that div, so the body's only flex child is the wrapper and
   `main` is a grandchild: putting the column on the body leaves main with
   nothing to fill and the footer floating fifty pixels short of the bottom
   on any screen taller than the content. Ported from a prototype that had
   no wrapper, found by measuring the footer instead of reading it. */
.errpage .wp-site-blocks{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}
/* On a phone these are one column, and centring them in the leftover
   height put each page's heading at a different distance from the
   header depending on how many links it offered. Start them all at
   the same place instead, and only centre once the layout is two
   columns and the block is short enough for centring to mean
   something. */
/* grid, not flex: a flex item would have to be told to fill, and a
   width on .lost beats the gutter .wrap sets and drops the type onto
   the page edge. align-content does the same job with nothing to
   undo. */
.errpage main{flex:1;display:grid;align-content:start;padding:clamp(2.2rem,6vw,3rem) 0}
@media (min-width:1000px){
  .errpage main{align-content:center;padding:clamp(3rem,7vw,4.5rem) 0}
}
.lost{display:grid;gap:2.2rem}
@media (min-width:1000px){.lost{grid-template-columns:1fr 1fr;gap:4.5rem;align-items:center}}
.lost h1{font-size:clamp(2.3rem,1.6rem + 3.2vw,4.2rem);max-width:14ch;margin-top:.5rem}
.lost h1 em{font-style:normal;color:var(--ink-soft)}
.lost .say{font-size:var(--t-m);line-height:1.45;max-width:34ch;margin:1.1rem 0 0;color:var(--ink-soft)}
.tries{margin:0;border-top:2px solid var(--ink)}
.tries a{display:grid;grid-template-columns:1fr auto;gap:.2rem 1.2rem;align-items:center;
  border-bottom:1px solid var(--line);padding:.95rem 0;text-decoration:none}
.tries b{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1.15}
.tries span{grid-column:1;color:var(--ink-soft);font-size:var(--t-s)}
/* the column has to be stated: a definite grid-row alone gets this
   placed before the auto items and it lands in column 1 */
.tries em{grid-row:1 / span 2;grid-column:2;font-style:normal;font-size:1.4rem;color:var(--ink-soft)}
.tries a:hover em{color:var(--ink)}
.thin{background:var(--navy);color:#eef1efb0;border-top:2px solid var(--yellow);font-size:var(--t-s)}
.thin-in{display:flex;flex-wrap:wrap;gap:.4rem 2rem;align-items:center;padding:.9rem 0}
.thin a{display:inline-flex;align-items:center;min-height:44px;color:#eef1efd8;text-decoration:none}
.thin a:hover{color:var(--yellow)}

/* ----------------------------------------------------------------
   MOTION : gentle. Gated on .js and reduced-motion.
   ---------------------------------------------------------------- */
.js .rise{opacity:0;transform:translateY(14px)}
@media (prefers-reduced-motion:reduce){
  .js .rise{opacity:1;transform:none}
  .pin .ring{animation:none}
  *{transition:none!important}
}

/* ================================================================
   PAGES

   Everything above is the shared system, ported from
   design/system.css. Everything below is one page's own CSS, ported
   from that page's <style> block, in the order the pages were built.

   The convention set above holds here too: where a colour is an alpha
   or a shade of a palette colour, the hex is the fallback and the
   real value is the color-mix inside the @supports beside it.
   ================================================================ */

/* ----------------------------------------------------------------
   THE SHOPS : the directory list
   design/shops.html
   ---------------------------------------------------------------- */

/* ---- the controls: search and view. .seg comes from the system.
   Shared sticky band with .filt below; the -in layout differs (grid
   here, wrapping flex there), so only the band itself is shared. ---- */
.ctl,.filt{position:sticky;top:var(--stick-top);z-index:var(--z-sticky);background:var(--paper);
  border-bottom:1px solid var(--line);padding:.75rem 0}
.ctl-in{display:grid;gap:.7rem}
@media (min-width:800px){.ctl-in{grid-template-columns:1fr auto;align-items:center;gap:1.2rem}}
.search{position:relative}
.search .in{padding-left:2.6rem}
.search svg{position:absolute;left:.9rem;top:50%;transform:translateY(-50%);
  width:18px;height:18px;stroke:var(--ink-soft);fill:none;stroke-width:2.2}
.count{font-size:var(--t-s);color:var(--ink-soft);white-space:nowrap}
.count b{color:var(--ink)}

/* ---- the register itself ---- */
.reg{padding:var(--band) 0}
.grp{margin-bottom:2.6rem}
.grp:last-child{margin-bottom:0}
/* the group letter sits in its own column on desktop so the list runs
   as one continuous register instead of restarting per block */
@media (min-width:1000px){
  .grp{display:grid;grid-template-columns:14rem 1fr;gap:0 3rem;align-items:start}
  .grp-lab{position:sticky;top:calc(var(--stick-top) + 5.2rem)}
}
/* the group is display:grid above, and a display value beats the
   hidden attribute, so a filtered-out group needs saying twice */
.grp[hidden]{display:none}
.grp-lab{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1.1;
  padding-bottom:.7rem;border-bottom:2px solid var(--yellow);margin-bottom:.4rem}

.row{
  display:grid;gap:.15rem;border-top:1px solid var(--line);
  padding:1.15rem 0;text-decoration:none;
}
/* .lead is the first row showing, not the first row in the markup.
   PHP puts it on the first one and the filter script moves it, so the
   hairline under the yellow rule is right in both states. */
.grp .row.lead{border-top:0}
@media (min-width:1000px){.grp .row.lead{border-top:1px solid var(--line)}}
.row h3{font-size:var(--t-m)}
.row .meta{color:var(--ink-soft);font-size:var(--t-s);margin:var(--sp-2xs) 0 0}
/* the bold lead-in is shared with the notice byline */
.row .meta b,.byline b{font-weight:700;color:var(--ink);text-transform:uppercase;letter-spacing:.08em}
.row .meta b + span::before{content:"\00a0\00b7\00a0"}
.row[hidden]{display:none}

.empty{padding:3rem 0;text-align:center;color:var(--ink-soft)}
.empty b{display:block;font-family:var(--disp);font-size:var(--t-m);color:var(--ink);margin-bottom:.4rem}

/* ---- map view ---- */
.mapview[hidden]{display:none}
.mapview{padding:var(--band) 0}

/* ---- the ask, at the bottom of a long list. Shared with .yours below,
   which is the same band on a different page. ---- */
.missing,.yours{background:var(--paper-2);border-block:1px solid var(--line)}
.missing-in,.yours-in{display:grid;gap:1.2rem;padding:calc(var(--band)*.7) 0;align-items:center}
@media (min-width:800px){.missing-in,.yours-in{grid-template-columns:1fr auto;gap:2.5rem}}
.missing h2,.yours h2{font-size:var(--t-l);max-width:22ch}
.missing p,.yours p{color:var(--ink-soft);margin:.7rem 0 0}
.missing p{max-width:52ch}
.yours p{max-width:54ch}
.missing .cta,.yours .cta{margin-top:0;white-space:nowrap}

/* ----------------------------------------------------------------
   ONE SHOP : the business listing
   design/shop.html
   ---------------------------------------------------------------- */

/* ---- the window: photo, name across the glass ---- */
.win{min-height:min(56vh,480px);display:flex;align-items:flex-end}
.win-bg{position:absolute;inset:0}
.win-bg img{width:100%;height:100%;object-fit:cover;object-position:center 42%}
/* Two scrims: one down from the top so the breadcrumb reads, one up
   from the bottom so the name does. The literals are the fallback,
   the color-mix beside them is the real value, same as everywhere
   else in this file. */
.win-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(to bottom,#101824bd 0%,#1018246e 15%,#10182400 33%),
  linear-gradient(to top,#101824f2 0%,#101824b0 34%,#10182430 70%,#10182412 100%)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .win-bg::after{background:
    linear-gradient(to bottom,
      color-mix(in srgb,var(--photo-ink) 74%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 43%,transparent) 15%,
      transparent 33%),
    linear-gradient(to top,
      color-mix(in srgb,var(--photo-ink) 95%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 69%,transparent) 34%,
      color-mix(in srgb,var(--photo-ink) 19%,transparent) 70%,
      color-mix(in srgb,var(--photo-ink) 7%,transparent) 100%)}
}
:root[data-hc="1"] .win-bg img{display:none}
:root[data-hc="1"] .win-bg::after{background:var(--photo-ink)}
/* no width here: this element is also .wrap and a width would beat
   the gutter that .wrap sets, dropping the type onto the page edge */
.win-in{position:relative;padding:0 0 clamp(1.6rem,4vw,2.6rem)}

.win h1{font-size:clamp(2.3rem,1.6rem + 3.4vw,4.6rem);max-width:16ch}
/* the sign and the name, on one baseline. The mark drops above the
   name on a phone rather than stealing a third of the line. */
.win-name{display:flex;flex-direction:column;align-items:flex-start;gap:.9rem}
@media (min-width:800px){.win-name{flex-direction:row;align-items:center;gap:1.4rem}}
.win-cr{position:absolute;right:.9rem;top:.6rem;font-size:.7rem;color:#eef1efc9;letter-spacing:.04em;
  text-shadow:0 1px 3px var(--photo-ink)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .win-cr{color:color-mix(in srgb,var(--on-navy) 79%,transparent)}
}

/* ---- a shop's own sale or promotion, #22 ---- */
.offers{background:var(--paper-2);border-bottom:1px solid var(--line)}
.offers-in{display:grid;gap:1.4rem;padding:1.4rem 0}
@media (min-width:700px){.offers-in{grid-template-columns:repeat(auto-fit,minmax(16rem,1fr))}}
.offer .kick{display:block;margin-bottom:var(--sp-3xs)}
.offer h2{font-size:var(--t-m)}
.offer p{color:var(--ink-soft);margin:.4rem 0 0}
.offer .when{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.08em;color:var(--ink)}

/* ---- open or closed, right now. The one fact worth the space. ---- */
/* Shared with .till below: the two status bands. */
.state,.till{background:var(--paper-2);border-bottom:1px solid var(--line)}
.state-in,.till-in{display:flex;flex-wrap:wrap;padding:1rem 0}
.state-in{align-items:center;gap:.6rem 1.4rem}
.dot{width:13px;height:13px;border-radius:50%;background:var(--ink-soft);flex:none;
  border:2px solid var(--ink)}
.dot.open{background:var(--yellow)}
/* the bold fact. .p-row .n, the preview card's shop name, is the same set */
.state b,.till b,.p-row .n{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1.1}
.state span,.till span{color:var(--ink-soft);font-size:var(--t-s)}
.state .acts{margin-left:auto;display:flex;flex-wrap:wrap;gap:.6rem}
/* one of the pill family: base and ink fill live under BUTTONS AND
   PILLS. Here is only its size, and the yellow call-first variant. */
.state .acts a{letter-spacing:.04em;padding:0 1.15rem;min-height:46px}
.state .acts a.pri{background:var(--yellow);border-color:var(--yellow);color:var(--navy)}
.state .acts a.pri:hover{background:#e5a51f;border-color:#e5a51f;color:var(--navy)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .state .acts a.pri:hover{
    background:color-mix(in srgb,var(--yellow) 88%,var(--navy));
    border-color:color-mix(in srgb,var(--yellow) 88%,var(--navy))}
}

/* ---- body: the words on the left, the facts on the right ----
   The same working layout carries the contact page (.msg) and the
   join page (.work); only the column split and the wide gap differ,
   and those live at each page's own site. */
.body,.msg,.work{display:grid;gap:2.6rem;padding:var(--band) 0}
@media (min-width:1000px){
  .body,.msg,.work{gap:4.5rem;align-items:start}
  .body{grid-template-columns:1.25fr .75fr}
}
.about p{font-size:clamp(1.12rem,1.03rem + .4vw,1.32rem);line-height:1.62;max-width:60ch}
.about p:first-of-type{font-size:clamp(1.25rem,1.1rem + .7vw,1.6rem);line-height:1.5}

/* ---- the hours ledger: today gets the yellow underline ---- */
/* The rule that opens the block is on the heading now, because the heading
   moved out of the dl: a dl may only hold dt/dd, so an h2 inside it was an
   invalid content model. Same line in the same place on screen. */
.hours-h{margin:2.4rem 0 0;padding:0 0 var(--sp-2xs);border-top:1px solid var(--line);
  font-size:var(--t-m)}
.hours{margin:0}
.hours-note{font-size:var(--t-s);color:var(--ink-soft);margin-top:.9rem}
.hrow{display:grid;grid-template-columns:6.6rem 1fr;border-bottom:1px solid var(--line);
  align-items:baseline;position:relative;padding:.7rem 0}
/* the day column is the shared small-caps label, up with .field */
.hrow dd{margin:0;font-size:var(--t-b);font-variant-numeric:tabular-nums}
.hrow.shut dd{color:var(--ink-soft)}
/* The yellow used to be a bar down the left of the row, which needed .9rem
   of padding to sit in, so today's day name started 14.4px right of the
   other six. This page is a ledger and the left edge is the whole point of
   it.

   Now it underlines the day name instead, which is the same yellow rule the
   category rows use on hover. It costs no layout, so all seven days keep the
   same x, and it marks the word rather than the row, so there is nothing to
   work out about which side of a line today is on. */
.hrow.now dt{text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:3px;text-underline-offset:.25em}
/* The marker sits under the day name at every width. There used to be a
   second version above 480 that put it on the same line as a "· today",
   but the day column is 8.5rem there and WEDNESDAY is already most of it,
   so it wrapped anyway and printed a bare dot at the start of the line.

   inline-block, not block: the yellow underline on the dt would otherwise
   propagate into this and draw a second rule under the word "today". A
   decoration does not cross into an atomic inline. */
.hrow.now dt::after{content:"today";display:inline-block;width:100%;margin-top:.15rem;
  color:var(--ink-soft);font-weight:400;letter-spacing:0;text-transform:none;
  text-decoration:none}
@media (min-width:620px){
  .hrow{grid-template-columns:8.5rem 1fr}
}

/* ---- the facts rail ---- */
@media (min-width:1000px){.rail{position:sticky;top:calc(var(--stick-top) + 1.4rem)}}
.rail h2{font-size:var(--t-m);margin-bottom:.9rem}
.rail .lmap{height:clamp(240px,32vw,320px);margin-bottom:1.2rem}
.rail a.link{color:var(--ink);text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:3px;text-underline-offset:.2em;word-break:break-word}
.rail a.link:hover{text-decoration-color:var(--ink)}

/* ---- walk on: the doors either side of this one ----
   The news page's next-and-back (.thumb/.tn) is this same two-door
   band, so the doors are written once. .tn's own measure and its
   time line live at its site. */
.walk{background:var(--paper-2);border-block:1px solid var(--line)}
.walk-in,.thumb-in{display:grid;gap:0}
@media (min-width:800px){.walk-in,.thumb-in{grid-template-columns:1fr 1fr}}
.door,.tn{display:block;text-decoration:none;padding:calc(var(--band)*.5) 0;border-top:1px solid var(--line)}
@media (min-width:800px){
  .door,.tn{border-top:0;padding:calc(var(--band)*.55) 0}
  .door + .door,.tn + .tn{border-left:1px solid var(--line);padding-left:2.5rem}
}
.door .kick,.tn .kick{display:block;margin-bottom:var(--sp-3xs)}
.door h2,.tn h2{font-size:var(--t-m)}
.door p{color:var(--ink-soft);font-size:var(--t-s);margin:.3rem 0 0}
.door.next,.tn.fwd{text-align:left}
@media (min-width:800px){.door.next,.tn.fwd{text-align:right}}
/* A listing with no photograph yet. The design assumed one; without it
   the band is four hundred pixels of flat navy above the name, which
   reads as a picture that failed to load rather than as a shop that
   has not sent one in. Same band, sized to its type. */
.win-bare{min-height:0;padding-top:calc(var(--band)*.55)}

/* ----------------------------------------------------------------
   WHAT'S ON : the calendar
   design/events.html
   ---------------------------------------------------------------- */

/* ---- the season strip: the Sundays, drawn ---- */
.season-in{padding:calc(var(--band)*.6) 0 calc(var(--band)*.5)}
/* white, not a theme colour: this band stays navy in all four themes */
.season h1{max-width:16ch}
/* One lede, like every other head on the site. It used to be two bold
   lines, an event and the market, each shouting to be the headline. A
   head leads with one thing; when both apply they share a sentence. */
.season .lede{font-size:var(--t-m);line-height:1.45;max-width:40ch;margin:var(--sp-s) 0 0;color:#eef1efe0}
.season .lede a{color:inherit;text-decoration-color:var(--yellow);text-underline-offset:3px}
.season .lede a:hover{color:#fff}
@supports (color:color-mix(in srgb,red 50%,white)){
  .season .crumb,.season .crumb a{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
  .season .lede{color:color-mix(in srgb,var(--on-navy) 88%,transparent)}
}


/* ---- the toggle strip: see .ctl above for the shared band ---- */
.filt-in{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1.2rem}
.filt .count{margin-left:auto;font-size:var(--t-s);color:var(--ink-soft);white-space:nowrap}
.filt .count b{color:var(--ink)}

/* ---- the wall of months ---- */
.wall{padding:var(--band) 0}
.mon{margin-bottom:2.8rem}
.mon:last-child{margin-bottom:0}
@media (min-width:1000px){
  .mon{display:grid;grid-template-columns:13rem 1fr;gap:0 3rem;align-items:start}
  .mon-lab{position:sticky;top:calc(var(--stick-top) + 5rem)}
}
/* the month is display:grid above, and a display value beats the hidden
   attribute, so a month with nothing showing needs saying twice */
.mon[hidden]{display:none}
.mon-lab{font-family:var(--disp);font-weight:800;font-size:clamp(1.7rem,1.3rem + 1.4vw,2.5rem);
  line-height:1;border-bottom:2px solid var(--yellow);padding-bottom:.6rem;margin-bottom:.4rem}
.mon-lab small{display:block;font-family:var(--body);font-weight:400;font-size:var(--t-s);
  color:var(--ink-soft);margin-top:.45rem;letter-spacing:0}
/* one event: the date block, then everything else */
.eb{display:grid;grid-template-columns:4.4rem 1fr;gap:.35rem 1.3rem;
  border-top:1px solid var(--line);padding:1.4rem 0;text-decoration:none;align-items:start}
@media (min-width:620px){.eb{grid-template-columns:5.6rem 1fr;gap:.35rem 2rem}}
.eb[hidden]{display:none}
/* .lead is the first row showing, same as the shops register */
.mon .eb.lead{border-top:0}
@media (min-width:1000px){.mon .eb.lead{border-top:1px solid var(--line)}}
.eb-d{grid-row:1 / span 3;text-align:center;border:1px solid var(--line);border-radius:4px;
  background:var(--card);padding:.6rem .2rem .55rem;line-height:1}
.eb-d b{display:block;font-family:var(--disp);font-weight:800;
  font-size:clamp(1.5rem,1.2rem + 1vw,2.1rem);font-variant-numeric:tabular-nums}
/* the label had the body's 1.65 line-height, so about six pixels of
   empty box sat under three capital letters and the tile read
   bottom-heavy. Measured: ten above the numerals, sixteen below. */
.eb-d span{display:block;font-weight:700;font-size:.72rem;text-transform:uppercase;
  letter-spacing:.09em;color:var(--ink-soft);margin-top:.32rem;line-height:1}
.eb.on .eb-d{background:var(--yellow);border-color:var(--yellow)}
.eb.on .eb-d b,.eb.on .eb-d span{color:var(--navy)}
.eb h3{font-size:var(--t-m);grid-column:2}
.eb .when{grid-column:2;font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.08em;color:var(--ink-soft)}
.eb .d{grid-column:2;color:var(--ink-soft);margin:.2rem 0 0;max-width:60ch}
.eb .tags{grid-column:2;display:flex;flex-wrap:wrap;gap:.45rem;margin-top:.7rem}
.eb .tags span{font-weight:700;font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;
  border:1px solid var(--line);border-radius:999px;padding:.28rem .7rem;color:var(--ink-soft)}
.eb .tags span.free{border-color:var(--ink);color:var(--ink)}

/* ---- from the shops this week, #22. Below the town's own wall and never
   mixed into it: eighteen shops posting a Friday sale would bury Sidewalk
   Days in its own calendar. ---- */
.shop-offers{padding:calc(var(--band)*.6) 0}
.shop-offers h2{font-size:var(--t-l);margin-bottom:var(--sp-xs)}
.shop-offers-in{display:grid;gap:1.2rem}
@media (min-width:700px){.shop-offers-in{grid-template-columns:repeat(auto-fit,minmax(16rem,1fr))}}
.shop-offer{display:block;text-decoration:none;border:1px solid var(--line);
  border-radius:4px;background:var(--card);padding:1.2rem}
.shop-offer .kick{display:block;margin-bottom:var(--sp-3xs)}
.shop-offer h3{font-size:var(--t-m)}
.shop-offer .who{font-weight:700;font-size:var(--t-s);color:var(--ink-soft);margin:.2rem 0 0}
.shop-offer .d{color:var(--ink-soft);margin:.4rem 0 0}
.shop-offer .when{display:block;font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.08em;color:var(--ink);margin-top:.7rem}

/* ---- add your own: see .missing above, same band ---- */

/* ----------------------------------------------------------------
   ONE EVENT : the poster
   design/event.html
   ---------------------------------------------------------------- */
.post{position:relative;overflow:clip}
.post::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(135deg,#eef1ef00 0 22px,#eef1ef08 22px 24px)}
:root[data-hc="1"] .post::before{display:none}
.post-in{position:relative;padding:calc(var(--band)*.55) 0 calc(var(--band)*.7)}
/* the kicker has the date block under it, so it needs the extra air */
.post .kick{margin-bottom:1.4rem}
@supports (color:color-mix(in srgb,red 50%,white)){
  .post .crumb,.post .crumb a{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
}

/* the date, set as the picture, and read top to bottom the way you
   would say it: month, then the days, then which days those are */
.big{border-top:2px solid var(--yellow);border-bottom:2px solid var(--yellow);padding:1.3rem 0 1.5rem}
.big .mm{font-family:var(--disp);font-weight:800;color:var(--yellow);
  font-size:clamp(1.3rem,1rem + 1.6vw,2.2rem);letter-spacing:.02em;margin:0 0 .35rem}
.big .dd{font-family:var(--disp);font-weight:800;line-height:.86;color:#fff;
  font-size:clamp(4rem,1.9rem + 13vw,12rem);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;margin:0}
.big .dd em{font-style:normal;color:var(--yellow);font-size:.62em;
  vertical-align:.12em;padding:0 .06em}
.big .wk{display:flex;flex-wrap:wrap;gap:.35rem 1.5rem;align-items:baseline;margin:.85rem 0 0}
.big .wk b{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.14em;color:#fff}
.big .wk span{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.1em;color:#eef1efb5}
@supports (color:color-mix(in srgb,red 50%,white)){
  .big .wk span{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
}

.post h1{margin-top:1.5rem;max-width:15ch}
.post .sub{font-size:var(--t-m);line-height:1.45;max-width:38ch;margin:1rem 0 0;color:#eef1efdd}
@supports (color:color-mix(in srgb,red 50%,white)){
  .post .sub{color:color-mix(in srgb,var(--on-navy) 87%,transparent)}
}

.acts{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.9rem}
.acts .cta{margin-top:0}
/* Unscoped from .acts in session 9: the members header wants exactly this
   button and a second copy of it under another name is how two navy buttons
   end up looking slightly different. */
.ghost{
  display:inline-flex;align-items:center;justify-content:center;min-height:52px;
  font-weight:700;font-size:var(--t-s);letter-spacing:.06em;text-transform:uppercase;
  text-decoration:none;padding:0 1.6rem;background:none;color:var(--on-navy);
  border:1px solid #eef1ef6b;border-radius:6px;cursor:pointer;font-family:var(--body);
  transition:background .15s,border-color .15s,color .15s;
}
/* the hover is the shared on-navy fill, up with .dispbtn */
.saved{font-size:var(--t-s);color:#eef1efb5;margin:.8rem 0 0}
@supports (color:color-mix(in srgb,red 50%,white)){
  .ghost{border-color:color-mix(in srgb,var(--on-navy) 42%,transparent)}
  .saved{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
}

/* ---- the countdown strip ---- */
/* the band, b and span are shared with .state above */
.till-in{align-items:baseline;gap:.4rem 1.4rem}

/* ---- what happens ----
   .body is shared with the shop page and is defined there. What is here is
   the typography of editor-written content sitting inside it. */
.body .lede{font-size:clamp(1.25rem,1.1rem + .7vw,1.65rem);line-height:1.5;max-width:38ch}
.body > div > p{max-width:60ch;font-size:clamp(1.1rem,1.02rem + .35vw,1.28rem);line-height:1.62}

/* The running order: a timetable, not bullets.

   A plain definition list, which is what a volunteer typing in the editor
   produces, lays itself out on the grid below. There was a second path for
   markup wrapping each pair in a div, carried over from the prototype, and
   nothing on the site or in the editor has ever produced it.

   Scoped to .whathappens, which is only ever the event page's editor
   content. It used to read .body > div > dl, and .body is shared with the
   shop page, so it also caught the shop's hours ledger and laid seven days
   out on a two-column grid on top of each other. */
.order,.whathappens > dl{margin:2.4rem 0 0;border-top:1px solid var(--line)}
.order h2{font-size:var(--t-m);padding:0 0 .9rem}
.whathappens > dl{display:grid;grid-template-columns:5.9rem 1fr;gap:0 1.2rem;align-items:baseline}
@media (min-width:620px){.whathappens > dl{grid-template-columns:7.5rem 1fr}}
.order dt,.whathappens > dl dt{font-weight:700;font-size:var(--t-s);letter-spacing:.04em;
  font-variant-numeric:tabular-nums;color:var(--ink-soft);
  border-bottom:1px solid var(--line);padding:.85rem 0}
.order dd,.whathappens > dl dd{margin:0;border-bottom:1px solid var(--line);padding:.85rem 0}
.order dd b,.whathappens > dl dd b{display:block;font-family:var(--disp);font-weight:800;font-size:var(--t-b)}
.order dd span,.whathappens > dl dd span{color:var(--ink-soft);font-size:var(--t-s)}

/* ---- also on ---- */
.also{background:var(--paper-2);border-block:1px solid var(--line)}
.also-in{padding:calc(var(--band)*.7) 0}
.also h2{font-size:var(--t-l);margin-bottom:var(--sp-xs)}

/* ----------------------------------------------------------------
   HOME
   design/home.html
   ---------------------------------------------------------------- */

/* ---- hero: the street itself is the picture ---- */
.hero{border-bottom:1px solid var(--line);
  min-height:min(78vh,640px);min-height:min(78dvh,640px);display:flex;align-items:center}
@media (min-width:800px){.hero{min-height:min(86vh,760px);min-height:min(86dvh,760px)}}
/* no photograph, no six hundred pixels of flat navy waiting for one */
.hero-bare{min-height:0}
.hero-bg{position:absolute;inset:0}
.hero-bg img{width:100%;height:100%;object-fit:cover;object-position:center 38%}

/* Every photo hero parallaxes on scroll now (system.js), home included --
   one rule rather than repeating it in .hero-bg/.win-bg/.vhead-bg's own
   blocks, since all three need exactly the same buffer for exactly the
   same reason. 1.4, not a smaller number: sliding an image on scroll needs
   real headroom past the frame or it shows its own edge partway down the
   page, and the amount system.js moves it by is matched to this scale --
   raise one, raise the other. */
.hero-bg img,.win-bg img,.vhead-bg img{transform:scale(1.4);will-change:transform}
/* localised navy glass: keeps the type readable without killing the
   photograph. Literals are the fallback, the color-mix is the value. */
.hero-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(78deg,#101824e0 0%,#101824b8 42%,#10182440 68%,#10182412 100%),
  linear-gradient(to bottom,#10182480 0%,transparent 30%),
  linear-gradient(to top,#101824d6 0%,transparent 36%)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .hero-bg::after{background:
    linear-gradient(78deg,
      color-mix(in srgb,var(--photo-ink) 88%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 72%,transparent) 42%,
      color-mix(in srgb,var(--photo-ink) 25%,transparent) 68%,
      color-mix(in srgb,var(--photo-ink) 7%,transparent) 100%),
    linear-gradient(to bottom,color-mix(in srgb,var(--photo-ink) 50%,transparent) 0%,transparent 30%),
    linear-gradient(to top,color-mix(in srgb,var(--photo-ink) 84%,transparent) 0%,transparent 36%)}
}
:root[data-hc="1"] .hero-bg img{display:none}
:root[data-hc="1"] .hero-bg::after{background:var(--photo-ink)}
.hero-cr{position:absolute;right:.9rem;bottom:.6rem;z-index:1;
  font-size:.7rem;color:#eef1ef8c;letter-spacing:.04em}
@supports (color:color-mix(in srgb,red 50%,white)){
  .hero-cr{color:color-mix(in srgb,var(--on-navy) 55%,transparent)}
}
/* the max-width lives on an inner box, never on the .wrap itself.
   A narrower max-width on .wrap keeps its auto margins and centres
   the whole block, which put the hero type 212px right of the
   wordmark and every heading below it at 1440. */
.hero-wrap{position:relative;padding:clamp(3rem,10vw,6rem) 0 clamp(3.2rem,9vw,5.5rem)}
.hero-in{max-width:46rem}
/* the poster headline: tighter leading than the shared one, because it
   is set in two lines on purpose */
.hero h1{font-size:clamp(2.5rem,1.7rem + 3.4vw,4.4rem);line-height:1.05}
/* the line break in the headline is a wide-screen refinement; on a
   phone the words wrap where they land */
.hero h1 br{display:none}
@media (min-width:620px){.hero h1 br{display:inline}}
.hero .today-top,.hero .today-body b,.hero .today-body span{text-shadow:0 1px 3px #101824cc}

/* today card: plain words, real logic */
.today{max-width:34rem;margin-top:1.8rem;border-top:1px solid #eef1ef3d;padding:1.05rem 0 0}
.today-top{display:flex;gap:.55rem;color:#ccd5e0;padding:0 0 .4rem}
.today-top span::before{content:"\00b7\00a0"}
.today-top b{font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.1em}
.today-top span{font-size:var(--t-s)}
.today-body{margin-top:var(--sp-2xs)}
.today-body b{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1.15;display:block;color:#fff}
.today-body span{color:#c3cddb;font-size:var(--t-s)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .today{border-top-color:color-mix(in srgb,var(--on-navy) 24%,transparent)}
  .today-top{color:color-mix(in srgb,var(--on-navy) 82%,transparent)}
  .today-body span{color:color-mix(in srgb,var(--on-navy) 76%,transparent)}
}

/* ---- shop of the day ----
   A poster, not a card. The photograph is the band and the band is tall
   enough to be a photograph rather than a letterboxed strip of one. Type
   centred over it, one accent on it, and the accent is the button.

   The wash is a flat veil plus a soft pool behind the middle. A
   one-directional gradient guarantees nothing where centred type actually
   sits: the first version darkened the left edge and the type sat in the
   middle over a bright sky. Measured against the real photographs at 390,
   800 and 1280 before this line was written. */
.feat{
  position:relative;display:grid;align-content:center;
  min-height:clamp(26rem,74vh,34rem);
  background:var(--photo-ink);color:var(--on-navy);overflow:clip;
  border-block:1px solid var(--line);
  text-align:center;
}
@media (min-width:800px){.feat{min-height:clamp(32rem,78vh,44rem)}}

.feat-bg{position:absolute;inset:0}
.feat-bg img{width:100%;height:100%;object-fit:cover;object-position:center}
.feat-bg::after{content:"";position:absolute;inset:0;background:
  radial-gradient(ellipse 78% 76% at 50% 52%,#101824e0 0%,#10182499 58%,#10182433 100%),
  linear-gradient(#10182459,#10182459)}
@supports (color:color-mix(in srgb,red,blue)){
  .feat-bg::after{background:
    radial-gradient(ellipse 78% 76% at 50% 52%,
      color-mix(in srgb,var(--photo-ink) 88%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 60%,transparent) 58%,
      color-mix(in srgb,var(--photo-ink) 20%,transparent) 100%),
    linear-gradient(color-mix(in srgb,var(--photo-ink) 35%,transparent),
                    color-mix(in srgb,var(--photo-ink) 35%,transparent))}
}
/* A picture behind text is the first thing to go when somebody has asked
   for contrast. */
:root[data-hc="1"] .feat-bg img{display:none}
:root[data-hc="1"] .feat-bg::after{background:var(--photo-ink)}

/* No photograph: the shop's own category, drawn twice. Tiled small across
   the whole band, which is what stops a bare band being a flat field, and
   once enormous and low off the right edge. Every category gets a different
   ground and none of them is a grid.

   --feat-pattern comes off the section as an inline custom property,
   because the drawing is chosen per shop and a stylesheet cannot know
   which. */
.feat-bare{background-image:var(--feat-pattern,none);background-size:176px 176px}
:root[data-hc="1"] .feat-bare{background-image:none}
.feat-mark{display:none}
@media (min-width:800px){
  .feat-mark{display:block;position:absolute;inset:0;overflow:clip;pointer-events:none}
  .feat-mark .kicon{
    position:absolute;right:-3%;bottom:-26%;width:auto;height:150%;
    aspect-ratio:1;margin:0;stroke-width:.55;
    color:color-mix(in srgb,var(--on-navy) 10%,transparent);
  }
}
:root[data-hc="1"] .feat-mark{display:none}

.feat-in{position:relative;padding:calc(var(--band)*.9) 0;max-width:40rem;
  margin-inline:auto;display:grid;justify-items:center;gap:0}

.feat-tag{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.16em;margin:0 0 1rem;
  color:color-mix(in srgb,var(--on-navy) 72%,transparent)}
.feat h2{font-size:clamp(2.4rem,1.6rem + 3.4vw,4.2rem);line-height:1.02;
  max-width:16ch;color:#fff;text-shadow:0 2px 10px #101824a6;margin:0}

/* what they call themselves, then where they are. Drawn separators, so a
   shop with no address does not leave a hanging dot. */
.feat-meta{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:.3rem .8rem;margin:1rem 0 0;font-weight:700;font-size:var(--t-s);
  text-transform:uppercase;letter-spacing:.1em;
  color:color-mix(in srgb,var(--on-navy) 76%,transparent);text-shadow:0 1px 4px #101824a6}
.feat-meta:empty{display:none}
.feat-meta span+span::before{content:"·";margin-right:.8rem;opacity:.55}

.feat-d{font-size:var(--t-m);line-height:1.5;max-width:34ch;margin:1.2rem 0 0;
  color:color-mix(in srgb,var(--on-navy) 94%,transparent);text-shadow:0 1px 4px #101824a6}

/* The shop's own mark, when they have one. Never the letter tile: over a
   photograph at this size that is a grey square with a letter in it. */
.feat-logo{width:auto;height:clamp(52px,7vw,76px);max-width:min(60%,15rem);
  object-fit:contain;margin:0 0 1rem;
  filter:drop-shadow(0 2px 8px #101824a6)}

/* One yellow thing on the band. The second link is a quiet one beside it.

   Both are the same height and both centre their own text, so the label in
   the button and the label in the link sit on one line. They did not: the
   link was 44px against a button that is taller, and the underline pulled
   the eye down again. The rule is drawn as a box-shadow rather than a
   border, so it hangs under the text without changing the box. */
/* align-items:center, and both boxes the same height. Stretch made the link
   78px against a 52px button, so its centred label sat twelve pixels above
   the button's. Measured, both ways. line-height:1 on the row keeps a stray
   text node from setting the height instead. */
.feat-go{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:.8rem 1.6rem;margin:1.9rem 0 0;line-height:1}
.feat-go .cta,.feat-cat{display:inline-flex;align-items:center;justify-content:center;
  height:52px;min-height:52px;margin:0}
.feat-cat{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.09em;color:var(--on-navy);text-decoration:none;
  box-shadow:inset 0 -1px 0 color-mix(in srgb,var(--on-navy) 45%,transparent)}
.feat-cat:hover,.feat-cat:focus-visible{box-shadow:inset 0 -2px 0 var(--yellow)}

/* ---- badges ----
   Open, closing soon, closed. Green, yellow, grey, and the colour is never
   the only carrier: the badge says the words. Built as a row rather than a
   single chip because #22 puts a sale, a late night and an event tonight
   next to it, and they all come out of dta_business_badges(). */
.badges{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem;
  margin:1rem 0 0;padding:0;list-style:none}
.badge{display:inline-flex;align-items:center;gap:.5rem;
  padding:.3rem .8rem;border-radius:999px;
  font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.08em;
  background:#101824a6;color:var(--on-navy);
  border:1px solid color-mix(in srgb,var(--on-navy) 26%,transparent)}
.badge i{width:9px;height:9px;border-radius:50%;flex:none;background:currentColor}
.badge[data-state="open"] i{background:var(--open)}
.badge[data-state="soon"] i{background:var(--yellow)}
.badge[data-state="closed"] i{background:color-mix(in srgb,var(--on-navy) 55%,transparent)}
/* the ring is the live one, and it stops for anybody who asked for no motion */
.badge[data-state="open"] i{animation:badge-ping 2.4s ease-out infinite}
@keyframes badge-ping{
  0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--open) 65%,transparent)}
  70%,100%{box-shadow:0 0 0 7px color-mix(in srgb,var(--open) 0%,transparent)}
}
@media (prefers-reduced-motion:reduce){.badge i{animation:none}}

/* .badges centers by default for the featured band; the event poster is
   left-set like everything else in it. Placed after .badges itself on
   purpose -- same specificity, and a copy of this sitting earlier in the
   file lost the cascade to .badges's own justify-content and margin,
   which is why this badge sat centred and hard against the date block's
   top border instead of left-aligned with breathing room under it. */
.post-badges{justify-content:flex-start;margin:0 0 1.4rem}
.badge[data-state="community"] i,.badge[data-state="shop"] i{background:var(--yellow)}

/* over flat ink a shadow reads as a smudge rather than as depth */
.feat-bare h2,.feat-bare .feat-d,.feat-bare .feat-meta{text-shadow:none}

/* Measured at 2.94:1 over the bright corner of a real photograph at 1280,
   which is not enough for seven-tenths of a rem. Opaque, with the same
   shadow the rest of the band carries, and its own small pool under it. */
.feat-cr{position:absolute;right:0;bottom:0;padding:.5rem .9rem .45rem 1.6rem;
  font-size:.7rem;color:color-mix(in srgb,var(--on-navy) 88%,transparent);
  text-shadow:0 1px 3px #101824;
  background:radial-gradient(120% 160% at 100% 100%,#101824b3 0%,#10182400 72%)}
/* ---- the six kinds of place ----
   A ledger, like every other block on this site. Six rows that do not move,
   do not pick anybody, and answer the question somebody actually landed
   here with. */
.kinds{display:grid;gap:0;border-top:1px solid var(--line);margin-top:1.8rem}
@media (min-width:620px){.kinds{grid-template-columns:1fr 1fr;column-gap:3.5rem}}
@media (min-width:1000px){.kinds{grid-template-columns:repeat(3,1fr);column-gap:3.5rem}}
.kind{display:flex;align-items:center;gap:.95rem;text-decoration:none;
  min-height:60px;padding:1.15rem 0;border-bottom:1px solid var(--line)}
/* the top rule belongs to the grid, so the first row of each column must
   not draw a second one under the heading */
@media (min-width:620px){.kind:nth-child(-n+2){border-top:0}}
@media (min-width:1000px){.kind:nth-child(-n+3){border-top:0}}
.kind h3{font-size:var(--t-m);margin:0}
/* Beside the name, not over it. Rob's call, session 12. It costs the left
   edge the rest of the page is built on, and it buys a row you read in one
   pass instead of two: the drawing and the words it belongs to are on the
   same line, the way they are on every other ledger on this site. */
.kicon{display:block;width:26px;height:26px;flex:none;
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
  color:var(--ink-soft);transition:color .15s}
.kind:hover .kicon{color:var(--ink)}

/* ---- from the archives: the one licensed piece of skeuomorphism ---- */
.archb{display:grid;gap:1.6rem}
@media (min-width:1000px){.archb{grid-template-columns:1.1fr .9fr;gap:3rem;align-items:start}}
.arch-img{margin:0;background:var(--paper-2);border-radius:4px;
  display:grid;place-items:center;height:clamp(280px,38vw,430px);padding:1.4rem}
.arch-img .mount img{max-height:calc(clamp(280px,38vw,430px) - 3.2rem)}
.arch-txt h3{font-size:var(--t-m)}
.arch-txt p{max-width:52ch;margin:.6rem 0 0}
.arch-cr{font-size:var(--t-s);color:var(--ink-soft)}
/* Back, Next and Pause do nothing without script, so they are not there
   without it. Gated on body.js the same way .rise is, and gated with display
   rather than the hidden attribute because a display value beating hidden is
   a mistake this stylesheet has already made more than once. The photograph,
   its caption and the credit are all server-rendered and stay. */
.arch-nav{display:none}
.js .arch-nav{display:flex;align-items:center;gap:.6rem;margin-top:1.2rem}
.arch-count{font-size:var(--t-s);color:var(--ink-soft);min-width:4rem;text-align:center}


/* ----------------------------------------------------------------
   NEWS : the notices
   design/news.html
   ---------------------------------------------------------------- */

/* one column, reading measure, centred. The whole page is this. */
.col{width:min(100% - (var(--gut)*2),44rem);margin-inline:auto}

/* ---- the one at the top: newest or pinned, in full ---- */
/* the tint needs real padding or it runs right to the text. Pulling
   the panel out by the same amount it pads keeps the words on the
   same left edge as everything else in the page, so the notice
   reads as pinned over the page rather than indented inside it. The
   photo, when there is one, bleeds to that same pulled-out edge --
   padding lives on .pin-note-body instead of the card itself so the
   image isn't fighting an inset it doesn't want. */
.pin-note{border-top:3px solid var(--yellow);border-bottom:1px solid var(--line);
  --pad:min(var(--gut),1.7rem);
  margin:0 calc(var(--pad) * -1);
  background:var(--paper-2)}
.pin-note-img{aspect-ratio:16/9;overflow:hidden}
.pin-note-img img{display:block;width:100%;height:100%;object-fit:cover}
.pin-note-body{padding:1.7rem var(--pad) 2rem}
@media (min-width:800px){
  .pin-note:not(.pin-note-bare){display:grid;grid-template-columns:minmax(0,42%) 1fr;align-items:stretch}
  .pin-note:not(.pin-note-bare) .pin-note-img{aspect-ratio:auto}
}
.pin-note .flag{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink-soft)}
.pin-note h2{font-size:clamp(1.7rem,1.3rem + 1.8vw,2.7rem);margin:.55rem 0 .3rem;max-width:22ch}
/* the time is the same date label the news cards use: see .item time */
.pin-note p{font-size:clamp(1.12rem,1.03rem + .4vw,1.3rem);line-height:1.62;margin:1rem 0 0}
.pin-note .more{margin-top:1.3rem;background:var(--card)}

/* ---- the stack: date in the margin, one line each ---- */
.stack{padding:0 0 var(--band)}
.yr{display:flex;align-items:baseline;gap:1.1rem;margin:2.6rem 0 0}
.yr h2{font-family:var(--disp);font-weight:800;font-size:var(--t-m);white-space:nowrap}
.yr::after{content:"";flex:1;height:2px;background:var(--yellow)}
.yr span{font-size:var(--t-s);color:var(--ink-soft);white-space:nowrap}

.note{display:grid;grid-template-columns:1fr;gap:.25rem;
  border-bottom:1px solid var(--line);padding:1.15rem 0;text-decoration:none}
@media (min-width:620px){
  .note{grid-template-columns:6.4rem 1fr;gap:.25rem 1.6rem;align-items:baseline}
  .note time{grid-row:1 / span 2}
  .note:not(.note-bare){grid-template-columns:6.4rem 4rem 1fr}
  .note:not(.note-bare) .note-thumb{grid-row:1 / span 2}
}
.note time{font-weight:700;font-size:var(--t-s);text-transform:uppercase;
  letter-spacing:.07em;color:var(--ink-soft);white-space:nowrap;font-variant-numeric:tabular-nums}
.note-thumb{width:3.5rem;height:3.5rem;object-fit:cover;border-radius:4px;margin-bottom:.35rem}
.note h3{font-size:clamp(1.2rem,1.1rem + .5vw,1.5rem);max-width:34ch}
.note p{color:var(--ink-soft);margin:.2rem 0 0;max-width:52ch;font-size:var(--t-s)}

/* ----------------------------------------------------------------
   ONE NOTICE : the memo
   design/article.html
   ---------------------------------------------------------------- */
.byline{display:flex;flex-wrap:wrap;gap:.3rem 1.5rem;align-items:baseline;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  margin-top:1.5rem;padding:.85rem 0;font-size:var(--t-s);color:var(--ink-soft)}
/* .byline b is the register rows' bold lead-in: see .row .meta b */

/* ---- the short version: the box that does the work ---- */
.short h2{font-size:var(--t-s);text-transform:uppercase;letter-spacing:.1em;
  font-family:var(--body);font-weight:700;color:var(--ink-soft);margin-bottom:.7rem}
.short ul{margin:0;padding:0;list-style:none}
.short li{display:grid;grid-template-columns:auto 1fr;gap:.8rem;align-items:baseline;
  padding:.42rem 0;font-size:clamp(1.1rem,1.02rem + .35vw,1.24rem);line-height:1.5}
.short li::before{content:"";width:9px;height:9px;background:var(--ink);border-radius:50%;
  transform:translateY(-.1em)}

/* ---- the notice itself ---- */
.text p{font-size:clamp(1.14rem,1.05rem + .42vw,1.34rem);line-height:1.68;margin:0 0 1.15em}
.text p:first-of-type{font-size:clamp(1.28rem,1.12rem + .75vw,1.68rem);line-height:1.5}
.text h2{font-size:var(--t-m);margin:2.1rem 0 .7rem}
.text ul{padding-left:1.15rem;margin:0 0 1.15em}
.text li{margin-bottom:.4em;font-size:clamp(1.14rem,1.05rem + .42vw,1.34rem);line-height:1.6}
.text ::marker{color:var(--yellow)}
.text strong{font-weight:700}

/* The numbers table, because a notice about money should show it.
   A definition list typed in the editor lands here, same as the
   running order on an event, so nobody has to learn a class name. */
.text > dl{margin:2rem 0;border-top:1px solid var(--line);
  display:grid;grid-template-columns:1fr auto;gap:0 1rem;align-items:baseline}
.text > dl dt{font-size:var(--t-b);border-bottom:1px solid var(--line);padding:.75rem 0}
.text > dl dd{margin:0;font-family:var(--disp);font-weight:800;
  font-variant-numeric:tabular-nums;border-bottom:1px solid var(--line);padding:.75rem 0}

/* ---- who wrote it ---- */
.sign{border-top:2px solid var(--yellow);margin-top:2.6rem;padding:1.4rem 0 0}
.sign p{margin:0 0 .5em;color:var(--ink-soft)}
.sign b{display:block;font-family:var(--disp);font-weight:800;font-size:var(--t-m);color:var(--ink)}
.sign .more{margin-top:1.1rem}

/* ---- next and back ----
   The band and the doors are the shop page's walk-on (.walk/.door);
   what is here is only .tn's own: a capped headline measure, and a
   time where a door has a category line. The band itself is also the
   privacy page's .nots, one band-and-margin rule for both. */
.thumb,.nots{background:var(--paper-2);border-block:1px solid var(--line);margin-top:var(--band)}
.tn h2{max-width:24ch}
.tn time{display:block;color:var(--ink-soft);font-size:var(--t-s);margin-top:.35rem}

/* ----------------------------------------------------------------
   ABOUT : who the group is
   design/about.html
   ---------------------------------------------------------------- */

/* ---- opening statement, no photograph ----
   The one page whose headline is the whole point, so it keeps a short
   measure. Everything else about it is the shared plain head. */
.phead-tight h1{max-width:15ch}
.phead-tight .lede{max-width:40ch;margin-top:1.3rem}

/* ---- what it does: four plain statements ---- */
.does{background:var(--paper-2);border-bottom:1px solid var(--line)}
.does-in{padding:var(--band) 0}
.does h2{font-size:var(--t-l);max-width:22ch;margin-bottom:var(--sp-s)}
/* the bordered ledger grid, shared with the visit page's distance
   list (.miles) and the contact page's doors (.doors). The two-column
   steps and gaps differ and live at each site. */
.jobs,.miles,.doors{display:grid;gap:0;border-top:1px solid var(--line)}
@media (min-width:1000px){.jobs{grid-template-columns:1fr 1fr;column-gap:4rem}}
.job{border-bottom:1px solid var(--line);padding:1.4rem 0}
@media (min-width:1000px){.job:nth-child(-n+2){border-top:0}}
.job h3{font-size:var(--t-m);max-width:20ch}
.job p{color:var(--ink-soft);margin:var(--sp-2xs) 0 0;max-width:46ch}

/* ---- the timeline: a spine down the page ---- */
.line{padding:var(--band) 0}
.line-kick{display:block;margin-bottom:var(--sp-3xs)}
.line > .wrap > h2{font-size:var(--t-l);max-width:20ch;margin-bottom:var(--sp-2xs)}
.line > .wrap > p{color:var(--ink-soft);max-width:52ch;margin:0 0 2.6rem}

/* the year drives both the dot and the spine. It is a clamp, so the
   old fixed `top` for the dot drifted with the viewport and was never
   actually level with the digits: too low at 820, too high at 1440.
   Both now sit on the middle of the year's own line box, plus one
   measured nudge for where digits sit inside it. */
.stop{position:relative;padding:0 0 2.8rem 0;--yr:clamp(1.6rem,1.3rem + 1.2vw,2.2rem)}
@media (min-width:800px){
  .stop{display:grid;grid-template-columns:7rem 1fr;gap:0 3rem;padding-bottom:3.4rem}
  /* the spine runs the full height of a stop so it joins the next one.
     Only the ends stop short: the first starts at its dot, the last
     finishes at its dot. */
  .stop::before{content:"";position:absolute;left:calc(7rem + 1.5rem - 1px);
    top:0;bottom:0;width:2px;background:var(--line)}
  .stop:first-of-type::before{top:calc(var(--yr) * .5)}
  .stop:last-of-type::before{bottom:auto;height:calc(var(--yr) * .5)}
  /* box-sizing is border-box, so the dot is 14px across including its
     border, not 18px. Half of 14 is 7. Measured at 1280 it sat 2px left
     of the spine for as long as this rule has existed. */
  .stop::after{content:"";position:absolute;left:calc(7rem + 1.5rem - 7px);
    top:calc(var(--yr) * .5);transform:translateY(-50%);
    width:14px;height:14px;border-radius:50%;background:var(--yellow);border:2px solid var(--ink)}
}
.stop-yr{font-family:var(--disp);font-weight:800;font-size:var(--yr);
  line-height:1;border-bottom:2px solid var(--yellow);padding-bottom:.5rem;margin-bottom:1rem;
  font-variant-numeric:tabular-nums}
@media (min-width:800px){.stop-yr{border-bottom:0;padding:0;margin:0;text-align:right}}
.stop-b h3{font-size:var(--t-m);max-width:26ch}
.stop-b p{margin:.6rem 0 0;max-width:56ch;font-size:clamp(1.08rem,1.02rem + .3vw,1.24rem);line-height:1.62}
.stop-b .cr{font-size:var(--t-s);color:var(--ink-soft);margin-top:.5rem}

/* mounted print inside a stop */
.stop figure{margin:1.3rem 0 0}
.stop .mount img{max-height:clamp(190px,26vw,300px)}
.stop.wide .mount img{max-height:clamp(210px,30vw,360px)}

/* ---- who runs it ---- */
.who{background:var(--navy);color:var(--on-navy);border-top:2px solid var(--yellow)}
.who-in{padding:var(--band) 0}
/* white, not a theme colour: this band stays navy in all four themes */
.who h2{font-size:var(--t-l);color:#fff;max-width:20ch}
.who > .who-in > .wrap > p{max-width:52ch;color:#eef1efdd;margin:1rem 0 0}
.who-note{margin-top:1.8rem}
/* the on-navy ledger grid, shared with the join board's terms. The
   column steps differ and live at each site. */
.roles,.terms{display:grid;gap:0;margin-top:2rem;border-top:1px solid var(--on-navy-line)}
@media (min-width:1000px){.roles{grid-template-columns:1fr 1fr;column-gap:4rem}}
.role{border-bottom:1px solid var(--on-navy-line);padding:1.2rem 0}
@media (min-width:1000px){.role:nth-child(-n+2){border-top:0}}
.role b{display:block;font-family:var(--disp);font-weight:800;font-size:var(--t-m);color:#fff}
.role span{display:block;color:#eef1efc4;margin-top:.35rem}
@supports (color:color-mix(in srgb,red 50%,white)){
  .who > .who-in > .wrap > p{color:color-mix(in srgb,var(--on-navy) 87%,transparent)}
  .role span{color:color-mix(in srgb,var(--on-navy) 77%,transparent)}
}

/* ---- the owned fact ---- */
.fact{padding:var(--band) 0}
.fact h2{font-size:clamp(1.8rem,1.4rem + 2vw,3.2rem);max-width:22ch}
.fact p{font-size:clamp(1.14rem,1.05rem + .42vw,1.34rem);line-height:1.65;max-width:58ch;margin:1.1rem 0 0}
.fact .src{font-size:var(--t-s);color:var(--ink-soft);margin-top:1.2rem}

/* ----------------------------------------------------------------
   PLAN A VISIT
   design/visit.html
   ---------------------------------------------------------------- */

/* ---- header over the water ---- */
.vhead{min-height:min(52vh,440px);display:flex;align-items:flex-end}
/* no photograph, no four hundred pixels of flat navy waiting for one */
.vhead-bare{min-height:0;padding-top:calc(var(--band)*.55)}
.vhead-bg{position:absolute;inset:0}
.vhead-bg img{width:100%;height:100%;object-fit:cover;object-position:center 55%}
.vhead-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(to bottom,#101824bd 0%,#1018246e 15%,#10182400 33%),
  linear-gradient(to top,#101824f0 0%,#101824a8 38%,#10182428 72%,#1018240f 100%)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .vhead-bg::after{background:
    linear-gradient(to bottom,
      color-mix(in srgb,var(--photo-ink) 74%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 43%,transparent) 15%,
      transparent 33%),
    linear-gradient(to top,
      color-mix(in srgb,var(--photo-ink) 94%,transparent) 0%,
      color-mix(in srgb,var(--photo-ink) 66%,transparent) 38%,
      color-mix(in srgb,var(--photo-ink) 16%,transparent) 72%,
      color-mix(in srgb,var(--photo-ink) 6%,transparent) 100%)}
}
:root[data-hc="1"] .vhead-bg img{display:none}
:root[data-hc="1"] .vhead-bg::after{background:var(--photo-ink)}
/* no width here: this element is also .wrap and a width would beat
   the gutter that .wrap sets, dropping the type onto the page edge */
.vhead-in{position:relative;padding:0 0 clamp(1.6rem,4vw,2.6rem)}
.vhead h1{max-width:15ch}
.vhead .lede{margin-top:1rem}
.vhead-cr{position:absolute;right:.9rem;top:.6rem;font-size:.7rem;color:#eef1efc9;
  text-shadow:0 1px 3px var(--photo-ink)}
@supports (color:color-mix(in srgb,red 50%,white)){
  .vhead .crumb,.vhead .crumb a{color:color-mix(in srgb,var(--on-navy) 77%,transparent)}
  .vhead .lede{color:color-mix(in srgb,var(--on-navy) 90%,transparent)}
  .vhead-cr{color:color-mix(in srgb,var(--on-navy) 79%,transparent)}
}

/* ---- how far: a plain distance ledger ---- */
.far{background:var(--paper-2);border-bottom:1px solid var(--line)}
.far-in{padding:calc(var(--band)*.6) 0}
.far h2{font-size:var(--t-l);margin-bottom:var(--sp-xs)}
.far-note{font-size:var(--t-s);color:var(--ink-soft);margin-top:1.1rem}
/* the grid itself is shared: see .jobs on the about page */
@media (min-width:800px){.miles,.doors{grid-template-columns:1fr 1fr;column-gap:3.5rem}}
.mrow{display:grid;grid-template-columns:1fr auto auto;gap:.4rem 1.2rem;align-items:baseline;
  border-bottom:1px solid var(--line);padding:.85rem 0;margin:0}
@media (min-width:800px){.mrow:nth-child(-n+3){border-top:0}}
.mrow b{font-weight:400;font-size:var(--t-b)}
.mrow .t{font-family:var(--disp);font-weight:800;font-size:var(--t-m);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.mrow .k{font-size:var(--t-s);color:var(--ink-soft);white-space:nowrap;min-width:4.5rem;text-align:right}

/* ---- the map with layers ---- */
.mapsec{padding:var(--band) 0}
.layers{display:flex;flex-wrap:wrap;gap:.6rem;margin-bottom:1.1rem}
/* one of the pill family: base, hover and pressed fill live under
   BUTTONS AND PILLS. Here is only its size and the gap for its key dot. */
.lbtn{min-height:46px;padding:0 1.15rem;gap:.55rem}
.lbtn i{width:11px;height:11px;border-radius:50%;flex:none;border:2px solid currentColor}
.lbtn[data-l="shops"] i{background:var(--yellow)}
.lbtn[data-l="parking"] i{background:var(--wp--preset--color--parking);border-radius:2px}
.lbtn[data-l="washroom"] i{background:var(--wp--preset--color--washroom)}
.lbtn[data-l="water"] i{background:none}
.mapsec .lmap{height:clamp(380px,52vw,560px)}

/* the non-shop pins. Their two colours are in theme.json beside every
   other colour on the site; they are map keys, not decoration, and a
   blue square has to stay a blue square in dark mode and in contrast. */
.pin.parking{background:var(--wp--preset--color--parking);border-radius:2px}
.pin.washroom{background:var(--wp--preset--color--washroom)}
.pin.water{background:none;border-color:var(--yellow)}
.pin.parking .ring,.pin.washroom .ring{display:none}

/* ---- three plans by how long you have ---- */
.plans{background:var(--paper-2);border-block:1px solid var(--line)}
.plans-in{padding:var(--band) 0}
.plans-kick{display:block;margin-bottom:var(--sp-3xs)}
.plans h2{font-size:var(--t-l);max-width:22ch}
.plans > .plans-in > .wrap > p{color:var(--ink-soft);max-width:52ch;margin:.8rem 0 0}
.pgrid{display:grid;gap:2.2rem;margin-top:2.2rem}
@media (min-width:1000px){.pgrid{grid-template-columns:repeat(3,1fr);gap:3rem}}
.plan{border-top:3px solid var(--ink)}
.plan:nth-child(2){border-top-color:var(--yellow)}
.plan h3{font-size:var(--t-m);padding-top:1.1rem}
.plan .sub{font-size:var(--t-s);color:var(--ink-soft);margin:.35rem 0 0}
.steps{margin:1.2rem 0 0;padding:0;list-style:none}
.steps li{display:grid;grid-template-columns:3.6rem 1fr;gap:.9rem;align-items:baseline;
  border-top:1px solid var(--line);padding:.8rem 0}
.steps li b{font-weight:700;font-size:var(--t-s);color:var(--ink-soft);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.steps li span{font-size:var(--t-b);line-height:1.5}

/* ---- good to know, expanded ---- */
.know{padding:var(--band) 0}
.know-kick{display:block;margin-bottom:var(--sp-3xs)}
.know h2{font-size:var(--t-l);max-width:24ch;margin-bottom:var(--sp-s)}

/* ----------------------------------------------------------------
   PRIVACY AND TERMS
   design/privacy.html. Terms of use was never drawn and uses this
   same layout, which is what the design says to do.

   Renamed on the way in, twice, because both names were taken:
   the design's .big is this theme's event date block, and its
   .yours is the paper-2 band on the shops page.
   ---------------------------------------------------------------- */

/* the answer, big, before anything else */
.answer{padding:calc(var(--band)*.7) 0 var(--band);border-bottom:1px solid var(--line)}
.answer h1{font-size:clamp(1.6rem,1.3rem + 1.2vw,2.2rem);color:var(--ink-soft);
  font-family:var(--body);font-weight:700;letter-spacing:0;max-width:24ch;margin-top:.6rem}
.answer .huge{font-family:var(--disp);font-weight:800;line-height:1.05;letter-spacing:-.01em;
  font-size:clamp(2.6rem,1.7rem + 4.4vw,5rem);margin:.7rem 0 0;max-width:16ch}
/* the answer sits in the ink colour like every other heading. An earlier
   draft set it in yellow with a navy stroke to force the contrast, which
   read as an outline effect rather than as type. The yellow does its
   normal job on the rule under it instead. */
.answer .huge em{font-style:normal;box-shadow:inset 0 -.14em 0 var(--yellow);padding:0 .05em}
.answer p{font-size:var(--t-m);line-height:1.45;max-width:38ch;margin:1.3rem 0 0;color:var(--ink-soft)}
.stamp{font-size:var(--t-s);color:var(--ink-soft);margin-top:1.8rem;padding-top:1rem;
  border-top:1px solid var(--line)}

/* the ledger: what it is, why, how long. Half a band, because the answer
   block above already ends on a full one. */
.what{padding:calc(var(--band)*.55) 0 0}
/* the same h2 carries the not-list below and the join page's
   what-happens-next band */
.what h2,.nots h2,.after h2{font-size:var(--t-l);max-width:22ch;margin-bottom:var(--sp-xs)}
.pitem{border-top:1px solid var(--line);padding:1.4rem 0}
.pitem:last-of-type{border-bottom:1px solid var(--line)}
.pitem h3{font-size:var(--t-m);max-width:28ch}
.pitem p{margin:.6rem 0 0;max-width:56ch;line-height:1.6}
.pitem dl{margin:1rem 0 0;display:grid;gap:.3rem 1.4rem;grid-template-columns:auto 1fr;
  font-size:var(--t-s)}
.pitem dt{font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-soft)}
.pitem dd{margin:0}

/* what it deliberately does not do. The band itself is written with
   the news page's .thumb; the h2 is up with .what. */
.nots-in{padding:var(--band) 0}
/* the bare bordered list is also the members page's .gaps */
.nots ul,.gaps{margin:0;padding:0;list-style:none;border-top:1px solid var(--line)}
.nots li{display:grid;grid-template-columns:1.7rem 1fr;gap:1rem;align-items:baseline;
  border-bottom:1px solid var(--line);padding:1rem 0}
.nots li::before{content:"\00d7";font-family:var(--disp);font-weight:800;font-size:1.5rem;
  color:var(--yellow);line-height:1}
/* The cross is a grid item too, so both of these have to name the column
   or the span drops back into the narrow first one. The join page's
   .after list sets its rows the same way, so the pairs are shared. */
.nots li b,.after li b{grid-column:2;font-family:var(--disp);font-weight:800;font-size:var(--t-b)}
.nots li span,.after li span{grid-column:2;color:var(--ink-soft)}
.nots-after{margin-top:1.6rem;color:var(--ink-soft);max-width:52ch}

/* your shop's listing: the bit that matters to a member */
.owner{padding:var(--band) 0}
.owner h2{font-size:var(--t-l);max-width:24ch;margin-bottom:var(--sp-xs)}
.owner p{max-width:58ch;line-height:1.62;margin:0 0 1em}
.owner .cta{margin-top:.8rem}

/* ----------------------------------------------------------------
   CONTACT
   design/contact.html

   A router before it is a form. Four doors first, because most of
   what gets typed into a form like this is already answered on
   another page, and the form is what is left over.
   ---------------------------------------------------------------- */
.chead{padding:calc(var(--band)*.7) 0 calc(var(--band)*.45)}
.chead h1{font-size:clamp(2.4rem,1.7rem + 3.2vw,4.4rem);max-width:14ch}
.chead-kick{display:block;margin:.4rem 0 .6rem}
.chead .lede{font-size:var(--t-m);line-height:1.45;max-width:38ch;margin:1rem 0 0;color:var(--ink-soft)}

/* ---- the router: four doors, pick one ---- */
.router{background:var(--paper-2);border-block:1px solid var(--line)}
.router-in{padding:calc(var(--band)*.7) 0}
.doors{display:grid;gap:0;border-top:1px solid var(--line)}
@media (min-width:800px){.doors{grid-template-columns:1fr 1fr;column-gap:3.5rem}}
.dr{display:block;text-decoration:none;border-bottom:1px solid var(--line);padding:1.4rem 0;
  position:relative}
@media (min-width:800px){.dr:nth-child(-n+2){border-top:0}}
.dr .kick{display:block;margin-bottom:var(--sp-3xs)}
.dr h2{font-size:var(--t-m);max-width:22ch}
.dr p{color:var(--ink-soft);margin:.5rem 0 0;max-width:44ch}
.dr .go{display:inline-flex;align-items:center;min-height:44px;margin-top:.35rem;
  font-weight:700;font-size:var(--t-s);text-transform:uppercase;letter-spacing:.06em}
.dr .go::after{content:"\00a0\2192"}

/* ---- the form, for what's left ----
   The band layout is shared with .body on the shop page; here is only
   the split this page and the join page (.work) use. */
@media (min-width:1000px){.msg,.work{grid-template-columns:1.1fr .9fr}}
.msg h2{font-size:var(--t-l);max-width:20ch}
.msg > div > p{color:var(--ink-soft);max-width:48ch;margin:.8rem 0 1.9rem}
.msg form,.work form{max-width:34rem}

/* What the form says back after a post. Yellow for the one that worked,
   because it is a receipt rather than an alarm, and the danger colour for
   the four that did not. Not colour alone: the wording carries it. */
.said{max-width:34rem;margin:0 0 1.6rem;padding:.9rem 1rem;line-height:1.5;
  border-left:4px solid var(--yellow);background:var(--paper-2)}
.said-no{border-left-color:var(--danger)}

/* The honeypot, off the side of the screen rather than display:none. Some
   form fillers skip a hidden input and none of them skip this one. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* who reads it, plain */
@media (min-width:1000px){.reads{position:sticky;top:calc(var(--stick-top) + 1.4rem)}}
.reads h3{font-size:var(--t-m);margin-bottom:.9rem}
.speed{margin:0;border-top:2px solid var(--ink)}
.srow{display:grid;grid-template-columns:1fr auto;gap:.3rem 1.2rem;align-items:baseline;
  border-bottom:1px solid var(--line);padding:.85rem 0}
.srow dt{font-size:var(--t-b)}
.srow dt span{display:block;font-size:var(--t-s);color:var(--ink-soft);margin-top:.2rem}
.srow dd{margin:0;font-family:var(--disp);font-weight:800;white-space:nowrap;
  font-variant-numeric:tabular-nums;color:var(--ink)}

/* ---- what this is and is not, over the theatre ---- */

/* ----------------------------------------------------------------
   GET LISTED
   From design/join.html. Mobile first: one column, the preview
   under the form, the offer band above both.
   ---------------------------------------------------------------- */

/* ---- the offer, stated once ----
   The navy board itself is the shared page head: see .phead-navy. */
.jhead-in{padding:calc(var(--band)*.65) 0}
.jhead .crumb,.jhead .crumb a{color:color-mix(in srgb,var(--on-navy) 71%,transparent)}
.jhead .crumb a:hover{color:var(--on-navy)}
.jhead .kick{color:var(--yellow);display:block;margin:var(--sp-3xs) 0}
.jhead h1{color:var(--on-navy);font-size:clamp(2.4rem,1.7rem + 3.2vw,4.4rem);max-width:15ch}
.jhead h1 em{font-style:normal;color:var(--yellow)}
.jhead .lede{font-size:var(--t-m);line-height:1.45;max-width:36ch;margin:1rem 0 0;
  color:color-mix(in srgb,var(--on-navy) 88%,transparent)}

/* the four terms. One per row on a phone, four across once there is
   room. The grid itself is shared: see .roles on the about page. */
.term{border-bottom:1px solid var(--on-navy-line);padding:1rem 0}
.term b{display:block;font-family:var(--disp);font-weight:800;font-size:var(--t-m);color:var(--on-navy)}
.term span{display:block;font-size:var(--t-s);margin-top:.25rem;
  color:color-mix(in srgb,var(--on-navy) 77%,transparent)}
@media (min-width:800px){
  .terms{grid-template-columns:repeat(4,1fr);column-gap:2rem;border-top:0}
  .term{border-top:1px solid var(--on-navy-line);border-bottom:0}
}

/* ---- the two columns: fill it in, watch it build ----
   The band layout is shared with .body, the split with .msg; only the
   wide gap is this page's own. .said already caps itself at 34rem. */
@media (min-width:1000px){.work{gap:4rem}}

fieldset{border:0;margin:0 0 2.4rem;padding:0}
legend{padding:0;margin-bottom:var(--sp-2xs);font-family:var(--disp);font-weight:800;
  font-size:var(--t-m);line-height:1.15}
.leg-note{font-size:var(--t-s);color:var(--ink-soft);margin:0 0 1.4rem;max-width:52ch}
.two{display:grid;gap:0 1.2rem}
@media (min-width:620px){.two{grid-template-columns:1fr 1fr}}

/* a box the form is complaining about. Not colour alone: it also carries
   aria-invalid, and the sentence at the top of the page names the field */
.in[aria-invalid="true"]{border-color:var(--danger);border-width:2px}

/* consent, said plainly. A 44px target, because this is the one control
   on the page that has to be hit first time */
.agree{display:grid;grid-template-columns:auto 1fr;gap:.9rem;align-items:start;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:1.3rem 0;margin:0 0 1.8rem;max-width:34rem}
.agree input{width:44px;height:44px;margin:0;accent-color:var(--ink);flex:none}
.agree input[aria-invalid="true"]{outline:2px solid var(--danger);outline-offset:2px}
.agree label{font-size:var(--t-b);line-height:1.55}
.agree .help{display:block;font-size:var(--t-s);color:var(--ink-soft);margin-top:var(--sp-2xs)}

/* ---- the week: seven rows of two times and a tick ----
   Mobile is a stack: the day, then the times, then Closed. At 620 the row
   turns into one line, which is where a week starts being readable as a
   week rather than as twenty-one controls. */
.week{border-top:1px solid var(--line)}
.wrow{display:grid;gap:.5rem .9rem;padding:.9rem 0;border-bottom:1px solid var(--line)}
@media (min-width:620px){
  .wrow{grid-template-columns:7.5rem 1fr auto;align-items:center;gap:.9rem}
}
/* .wday is the shared small-caps label, up with .field */
.wtimes{display:flex;align-items:center;gap:.6rem}
.wtime{width:auto;flex:1 1 auto;min-width:0;padding:.5rem .6rem;min-height:48px;
  font-variant-numeric:tabular-nums}
@media (min-width:620px){.wtime{flex:0 1 9rem}}
.wto{font-size:var(--t-s);color:var(--ink-soft)}
/* The tick and its word are one target, and the target is 44px tall. */
.wshut{display:inline-flex;align-items:center;gap:.6rem;min-height:44px;cursor:pointer;
  font-size:var(--t-s);text-transform:uppercase;letter-spacing:.08em;font-weight:700;
  color:var(--ink-soft)}
/* the same tick box carries the sign-in's remember-me */
.wshut input,.gate .login-remember input{width:24px;height:24px;margin:0;accent-color:var(--ink);flex:none}
.wshut:has(input:checked){color:var(--ink)}
/* A label that only a screen reader gets. Not the honeypot's .hp: that one is
   off the side of the screen on purpose and means something else. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}

/* ---- the preview rail ----
   Absent until a script has run, so there is no dead placeholder column
   with JavaScript off. Nothing here sets `display`, because a display
   value silently beats the hidden attribute and that has cost this
   project four bugs. */
@media (min-width:1000px){.prev{position:sticky;top:calc(var(--stick-top) + 1.4rem)}}
.prev > h2{font-size:var(--t-m);margin-bottom:.4rem}
.prev > p{font-size:var(--t-s);color:var(--ink-soft);margin:0 0 1.2rem;max-width:44ch}
.card{border:1px solid var(--line);border-radius:4px;background:var(--card);overflow:hidden}
.card + .card{margin-top:1.4rem}
.card-bar{margin:0;background:var(--paper-2);border-bottom:1px solid var(--line);
  padding:.5rem .9rem;font-size:.72rem;font-weight:700;text-transform:uppercase;
  letter-spacing:.09em;color:var(--ink-soft)}
.card-in{padding:1.2rem 1.1rem 1.4rem}
.card .logo-mark{margin-bottom:.9rem}
.p-cat{margin:0;font-size:var(--t-s);font-weight:700;text-transform:uppercase;
  letter-spacing:.09em;color:var(--ink-soft)}
.p-name{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1.1;margin:.35rem 0 0}
/* The design called this marker .empty. This theme already has an .empty,
   the nothing-here block on the shops and events lists, and it centres its
   text. Third class collision of its kind on this project: check style.css
   before inventing a short class. */
.p-empty{color:var(--ink-soft)}
.p-addr{font-size:var(--t-s);color:var(--ink-soft);margin:.3rem 0 0}
.p-desc{margin:.9rem 0 0;line-height:1.55}
.p-site{margin:.4rem 0 0;word-break:break-word;text-decoration:underline;
  text-decoration-color:var(--yellow);text-decoration-thickness:3px;text-underline-offset:.2em}
.p-site[hidden]{display:none}
.p-hours{margin:1.1rem 0 0;border-top:1px solid var(--line);padding-top:.7rem;
  font-size:var(--t-s);color:var(--ink-soft)}
.p-row{display:flex;flex-direction:column;gap:.15rem}
/* .p-row .n is the shop page's bold fact: see .state b */
.p-row .m{font-size:var(--t-s);color:var(--ink-soft);margin-top:.25rem}

/* ---- what happens next ---- */
.after{background:var(--paper-2);border-block:1px solid var(--line)}
.after-in{padding:calc(var(--band)*.8) 0}
/* the h2 is shared with the privacy page: see .what h2 */
.after ol{margin:0;padding:0;list-style:none;counter-reset:n}
.after li{display:grid;grid-template-columns:2.6rem 1fr;gap:1.2rem;align-items:baseline;
  border-top:1px solid var(--line);padding:1.15rem 0;max-width:58rem}
.after li::before{counter-increment:n;content:counter(n);font-family:var(--disp);
  font-weight:800;font-size:var(--t-m);color:var(--yellow);line-height:1}
/* the counter is a grid item too; the b and span pairs that name the
   column are shared with the privacy page's not-list, at .nots li b */
.after-note{margin-top:1.8rem;color:var(--ink-soft);max-width:56ch}

/* ----------------------------------------------------------------
   FOR MEMBERS
   From design/members.html. Two states in one stylesheet: the
   sign-in a stranger sees and the desk an owner sees.

   The design defined .ghost, .listhead, .facts and .more of its
   own. All four already existed here, so this file adds none of
   them back. .who was taken too, by the navy band on the about
   page, so the address label under the shop name is .ihead-at.
   ---------------------------------------------------------------- */

/* ---- the sign-in ---- */
.gate{display:grid;place-items:center;padding:var(--band) 0;min-height:58vh;min-height:58dvh}
.gate-box{width:min(100%,30rem)}
.gate .kick{display:block;margin-bottom:var(--sp-3xs)}
.gate h1{font-size:clamp(2rem,1.5rem + 2.4vw,3.2rem);max-width:16ch}
.gate > .gate-box > p{color:var(--ink-soft);margin:.9rem 0 1.8rem;max-width:38ch}
.gate .said{max-width:none}

/* core's markup, our shapes. wp_login_form prints p.login-username,
   p.login-password, p.login-remember and p.login-submit, so those are
   the hooks rather than anything this file gets to name. The box, its
   label and its input reuse .field and .in's rules up in FORMS, and
   the remember tick reuses the join form's .wshut input, rather than
   carrying a wholesale copy of each down here. */
.gate .login-remember{display:flex;align-items:center;gap:.7rem;margin:0 0 1.4rem;
  font-size:var(--t-s);color:var(--ink-soft)}
.gate .login-remember label{display:flex;align-items:center;gap:.7rem;min-height:44px}
.gate .login-submit{margin:0}
/* core's submit is <input type=submit>, so .cta cannot be put on it from
   the outside. Same shape, said once. */
.gate .login-submit input{
  display:block;width:100%;min-height:56px;border:0;border-radius:6px;cursor:pointer;
  font-family:var(--body);font-weight:700;font-size:var(--t-s);letter-spacing:.06em;
  text-transform:uppercase;background:var(--ink);color:var(--paper);
  transition:background .15s;
}
.gate .login-submit input:hover{background:var(--ink-soft)}

.gate .aside{font-size:var(--t-s);color:var(--ink-soft);border-top:1px solid var(--line);
  margin-top:1.8rem;padding-top:1.2rem;line-height:1.9}
/* Vertical padding on an inline element grows the hit area without growing
   the line box, so these stay tappable and the paragraph keeps its leading.
   min-height would have pushed the lines apart. */
.gate .aside a{padding-block:.88rem;
  text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:3px;text-underline-offset:.2em}

/* ---- signed in ----
   The navy board itself is the shared page head: see .phead-navy. */
.ihead-in{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 2rem;padding:calc(var(--band)*.5) 0}
.ihead .kick{color:var(--yellow);display:block;margin-bottom:var(--sp-3xs)}
.ihead h1{color:var(--on-navy);font-size:clamp(1.9rem,1.5rem + 2.2vw,3.1rem)}
.ihead .out{margin-left:auto;display:flex;flex-wrap:wrap;gap:.6rem;align-items:center}
.ihead-at{font-size:var(--t-s);color:color-mix(in srgb,var(--on-navy) 77%,transparent)}

/* ---- the two jobs ---- */
.jobs2{padding:var(--band) 0 calc(var(--band)*.5)}
.jobs2 > .wrap > h2{font-size:var(--t-l);max-width:20ch}
.jobs2 > .wrap > p{color:var(--ink-soft);max-width:50ch;margin:.8rem 0 0}
.deck{display:grid;gap:1.4rem;margin-top:2rem}
@media (min-width:800px){.deck{grid-template-columns:1fr 1fr;gap:2.5rem}}
.job2{border-top:3px solid var(--ink);padding-top:1.2rem}
.job2:nth-child(2){border-top-color:var(--yellow)}
.job2 h3{font-size:var(--t-m)}
.job2 p{color:var(--ink-soft);margin:.6rem 0 0;max-width:44ch}
.job2 ul{margin:1.2rem 0 0;padding:0;list-style:none;border-top:1px solid var(--line)}
.job2 li{border-bottom:1px solid var(--line);padding:.75rem 0;font-size:var(--t-b);
  display:grid;grid-template-columns:1.5rem 1fr;gap:.7rem;align-items:baseline}
.job2 li::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--yellow);
  border:2px solid var(--ink);transform:translateY(-.15em)}
.job2 .cta{margin-top:1.4rem}

/* ---- your listing, as it stands ---- */
.mine{background:var(--paper-2);border-block:1px solid var(--line)}
.mine-in{padding:var(--band) 0}
.mine h2{font-size:var(--t-l);margin-bottom:var(--sp-2xs)}
.mine > .wrap > p{color:var(--ink-soft);max-width:52ch;margin:0 0 1.7rem}
.sheet{display:grid;gap:2.4rem}
@media (min-width:1000px){.sheet{grid-template-columns:1.15fr .85fr;gap:3.5rem;align-items:start}}
.state-row{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1.2rem;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:.9rem 0;margin-bottom:1.5rem}
.chip{display:inline-flex;align-items:center;gap:.5rem;font-weight:700;font-size:var(--t-s);
  text-transform:uppercase;letter-spacing:.08em}
.chip i{width:11px;height:11px;border-radius:50%;background:var(--yellow);
  border:2px solid var(--ink);flex:none}
.state-row .when{font-size:var(--t-s);color:var(--ink-soft);margin-left:auto}

/* What is missing from your own listing. The only nagging an owner
   gets. The list itself is the privacy page's .nots ul, shared there. */
.gaps li{display:grid;grid-template-columns:1.6rem 1fr auto;gap:.9rem;align-items:baseline;
  border-bottom:1px solid var(--line);padding:.8rem 0}
.gaps li b{font-weight:400}
.gaps li em{font-style:normal;font-size:var(--t-s);color:var(--ink-soft);white-space:nowrap}
/* Not colour alone: the tick and the dot are different shapes, and the word
   beside them says Done or Still missing either way. */
.gaps .ok::before{content:"\2713";color:var(--ink);font-weight:700}
.gaps .no::before{content:"\2022";color:var(--yellow);font-size:1.6rem;line-height:.55}

/* ---- your account ---- */
.acct{padding:var(--band) 0}
.acct h2{font-size:var(--t-l);margin-bottom:var(--sp-2xs)}
.acct > .wrap > p{color:var(--ink-soft);max-width:54ch;margin:0 0 1.7rem}
.acct-grid{display:grid;gap:0}
@media (min-width:1000px){.acct-grid{grid-template-columns:1fr 1fr;column-gap:4rem}}
.acct-row{border-bottom:1px solid var(--line);padding:1.15rem 0;
  display:grid;grid-template-columns:1fr auto;gap:.3rem 1.2rem;align-items:center}
@media (min-width:1000px){.acct-row:nth-child(-n+2){border-top:1px solid var(--line)}}
.acct-row b{font-family:var(--disp);font-weight:800;font-size:var(--t-b);grid-column:1}
.acct-row span{grid-column:1;color:var(--ink-soft);font-size:var(--t-s);max-width:40ch}
.acct-row .more{grid-row:1 / span 2;grid-column:2}

/* ---- who's on the site ---- */
.roll{background:var(--paper-2);border-block:1px solid var(--line)}
.roll-in{padding:var(--band) 0}
.roll h2{font-size:var(--t-l);margin-bottom:var(--sp-2xs)}
.roll > .wrap > p{color:var(--ink-soft);max-width:52ch;margin:0 0 1.6rem}
.names{columns:2;column-gap:2.5rem;margin:0;padding:0;list-style:none;border-top:1px solid var(--line)}
@media (min-width:1000px){.names{columns:3}}
.names li{break-inside:avoid;border-bottom:1px solid var(--line);padding:.7rem 0;font-size:var(--t-b)}
.names li a{display:block;text-decoration:none}
.roll-note{font-size:var(--t-s);color:var(--ink-soft);margin-top:1.4rem}

/* ----------------------------------------------------------------
   THE WEATHER
   A thin strip under the header on every page. Server-rendered and
   cached; see dta_weather() for why it is not an embed.

   The drawings are masks over currentColor, the same trick the
   external-link arrow uses, so the icon takes whatever colour the
   band is using and never has to be drawn twice.
   ---------------------------------------------------------------- */
/* position:relative is for the forecast drawer, which hangs off the bottom
   edge of this band. The band is in normal flow under the fixed header, not
   sticky itself, so there is nothing above it to clip the drawer. */
.nowout{position:relative;background:var(--paper-2);border-bottom:1px solid var(--line)}

/* ---- the band shows the sky ----
   A photograph, under a wash, and the photograph has to be readable as
   weather from six feet away: a sun in the sky for clear, cumulus with the
   light behind them for partly cloudy, a curtain of rain, flakes across the
   frame, trees going into fog, a lightning bolt. The first set was chosen
   for "sky only, no landmark" and came out as six abstract colour fields,
   which is a set with nothing to say.

   The wash does two jobs. It guarantees a value behind the text, which a
   photograph cannot promise on its own: six pictures by six photographers
   have six different exposures. And it is what makes six strangers'
   photographs read as one set.

   It is a two-part wash. A flat veil over the whole band keeps the set
   consistent and is deliberately light, so the weather still shows. A second
   pass fades in from the left, over the third of the band the temperature
   and the condition sit on, and that is what actually carries the contrast.
   The far end stays clear, which is where the next few hours are going.

   One wash for daylight, one for after dark, and the picture underneath is
   the same either way. So the night sky is the day sky behind darker glass
   and there is no second set of six to keep in step.

   Fixed hex rather than theme tokens, deliberately, the same as the navy
   bands: the wash has to hold its value when the page turns dark, or the
   thing it is guaranteeing stops being guaranteed. */
.nowout[data-sky]{
  --veil:linear-gradient(#eef1ef2e,#eef1ef1f);
  --read:linear-gradient(90deg,#eef1efed 0%,#eef1efe0 24%,#eef1ef70 48%,#eef1ef00 66%);
  background-color:#dfe4e1;
  color:#16283e;border-bottom-color:#16283e2e;
}
.nowout[data-sky][data-day="0"]{
  --veil:linear-gradient(#0c162280,#0c162270);
  --read:linear-gradient(90deg,#0c1622f2 0%,#0c1622e6 24%,#0c16227a 48%,#0c162200 66%);
  background-color:#121d2b;
  color:#eef1ef;border-bottom-color:#eef1ef2e;
}
/* The photo and the wash used to be one background-image list on .nowout
   itself, three layers swapped in one instant tick when the hour turned
   over. Split into their own layers so the photo alone can fade -- the
   wash's job is guaranteeing contrast, not something that needs to move,
   and re-compositing it every tick would risk the exact contrast this band
   was built and measured against.
   .nowout-in needs position:relative and a z-index above these two, full
   stop -- a non-positioned element always paints below ANY positioned one
   regardless of DOM order, so without it the wash painted over the
   temperature and the icon instead of behind them.

   That alone is not the whole fix. Giving .nowout ITSELF a z-index (to make
   it a stacking context, so these two could use negative z-index instead)
   was tried and reverted: a stacking context traps its contents at its own
   position in the page's paint order, so .nowfc-panel -- which has to cover
   the section below this band when the drawer opens -- could no longer
   escape upward no matter what z-index it carried internally. .nowout
   stays a plain positioned element, not a stacking context, so its
   children's z-index competes against the rest of the page normally and
   the drawer can still paint over what comes after it.

   The remaining side effect -- .nowout-in becoming the *nearest* positioned
   ancestor, ahead of .nowout, for anything absolutely positioned inside it
   -- is real and is fixed at .nowfc-panel directly (below), not here. */
.nowout-photo{position:absolute;top:0;right:0;bottom:-1px;left:0;z-index:0;
  background-image:var(--sky-photo,none);background-size:cover;background-position:center;
  background-repeat:no-repeat;opacity:0;transition:opacity .8s ease}
.nowout-photo.on{opacity:1}
.nowout-wash{position:absolute;top:0;right:0;bottom:-1px;left:0;z-index:1;
  background-image:var(--read),var(--veil);background-size:cover;background-position:center}
.nowout-in{position:relative;z-index:2}
@media (prefers-reduced-motion:reduce){.nowout-photo{transition:none}}

.nowout[data-sky="sun"]  {--sky-photo:url("assets/img/sky/sun.jpg")}
.nowout[data-sky="cloud"]{--sky-photo:url("assets/img/sky/cloud.jpg")}
.nowout[data-sky="rain"] {--sky-photo:url("assets/img/sky/rain.jpg")}
.nowout[data-sky="snow"] {--sky-photo:url("assets/img/sky/snow.jpg")}
.nowout[data-sky="fog"]  {--sky-photo:url("assets/img/sky/fog.jpg")}
.nowout[data-sky="storm"]{--sky-photo:url("assets/img/sky/storm.jpg")}
/* a clear night is the clear day picture with the night wash over it */
.nowout[data-sky="moon"] {--sky-photo:url("assets/img/sky/sun.jpg")}

/* High contrast is somebody telling us they need the text to win. A sky
   behind it is decoration, so it comes off entirely and the band goes back
   to being paper with ink on it. */
:root[data-hc] .nowout[data-sky]{
  background:var(--paper-2);color:var(--ink);border-bottom-color:var(--line)}
:root[data-hc] .nowout-photo,:root[data-hc] .nowout-wash{display:none}
/* and with no photograph there is nothing for the chips to sit on top of, so
   the pill would be a grey blob on a plain band */
:root[data-hc] .nowout-next{background:none;padding-inline:0}
/* Centre, not baseline. The temperature is set at line-height 1 and
   everything beside it is body text at 1.6, so sharing a baseline put the
   number's box three pixels above the middle of the band. Measured. */
.nowout-in{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem .8rem;padding:.75rem 0}
.nowout-deg{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1;
  font-variant-numeric:tabular-nums}
.nowout-say{font-size:var(--t-b)}
/* ---- the next few hours ----
   Six chips at the far end of the band, in the room the observed note used to
   take. One line, no wrapping, no scrolling: a strip under the header is not
   a thing to swipe, so the ones that do not fit are simply not shown.

   Which is why the count is done in CSS rather than in PHP. The server always
   sends six and the width decides how many are readable, so there is no
   breakpoint in the markup and nothing to keep in step. */
/* The chips carry their own ground, as a pill.

   They sit at the far end of the band, which is exactly where the readability
   wash was faded out on purpose to let the photograph show. Measured over the
   real pixels, the hours came out at 1.05:1 on a rainy afternoon and failed
   in five of the six daylight skies. Invisible.

   A pill rather than widening the wash. Widening it to cover six chips at
   1280 leaves the photograph showing nowhere, and the pill fixes the exact
   width the text occupies at any screen size with no stops to tune. The
   radius is the one the display-options buttons already use. */
.nowout-next{
  display:flex;align-items:center;gap:.9rem;
  margin:0 0 0 auto;padding:.22rem .85rem;list-style:none;
  font-variant-numeric:tabular-nums;
  background:#eef1efdb;border-radius:999px;
}
.nowout[data-day="0"] .nowout-next{background:#0c1622d1}
.nowout-next li{display:flex;align-items:center;gap:.35rem;white-space:nowrap}
/* Celsius or Fahrenheit. The letter against the number, 25°C, in the same
   display face at the same size, so it reads as part of the reading rather
   than as a control parked beside one. A dotted underline says it does
   something.

   Both sit inside .nowout-deg, which is line-height 1, and both are plain
   inline text, so they share a baseline without being told to. The
   underline is a border, and a border on an inline box hangs below the
   baseline rather than moving it. */
.nowout-unit{
  font:inherit;color:inherit;text-decoration:none;
  border-bottom:1px dotted currentColor;
  margin-left:.05em;
  opacity:.62;transition:opacity .15s;
}
.nowout-unit:hover,.nowout-unit:focus-visible{opacity:1}
.nowout-at{font-size:var(--t-s);opacity:.72}
.nowout-t{font-weight:700;font-size:var(--t-s)}
.nowout-next .nowout-sky{width:1.05rem;height:1.05rem}
/* A phone gets the current temperature and what it is doing, and that is the
   whole answer at that width. The hours start at the two-column step.

   This used to have five stops of its own, at 420, 620, 820, 980 and 1120,
   because the chips were fitted one at a time against a ruler. They are on
   the site's four steps now. What that costs is one chip on a large phone
   held sideways, which used to show two hours between 420 and 620 and now
   shows none. Measured at each step: three chips clear the condition text by
   79px at 620 and four wrap it, four clear by 137px at 800, and six fit at
   1180. */
.nowout-next li+li{display:none}
@media (min-width:620px){.nowout-next li:nth-child(-n+3){display:flex}}
@media (min-width:800px){.nowout-next li:nth-child(-n+4){display:flex}}
@media (min-width:1000px){.nowout-next li:nth-child(-n+5){display:flex}}
/* :nth-child again rather than a bare li, so this keeps the same specificity
   as the rules above it and actually wins over the li+li that hides them */
@media (min-width:1180px){.nowout-next li:nth-child(-n+6){display:flex}}

/* ---- five days, in a drawer under the band ----
   Absent below the tablet step, not hidden: a phone gets the temperature and
   what it is doing, which is the whole answer at that width, and the chips it
   would sit beside are not there either.

   `details` does the opening and closing, so this works with no script at
   all. The panel hangs off the bottom edge rather than pushing the page down,
   because the band is the first thing under the header and shoving the hero
   forty pixels down the moment somebody presses a chevron reads as the page
   breaking. */
.nowfc{display:none}
@media (min-width:800px){.nowfc{display:block;margin-left:.5rem}}
/* The toggle sits at the far right of the band, past where --read guarantees
   a value behind it (see the comment above .nowout[data-sky]): that wash
   fades to nothing by two-thirds across, on purpose, so the next-few-hours
   strip stays a photograph. A control can't rely on that fade-out the way
   plain text can, so it carries its own always-on chip -- opaque enough that
   no sky photo underneath can break its contrast with the icon on top. */
.nowfc > summary{
  display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:999px;cursor:pointer;
  list-style:none;background:#eef1efd9;transition:background-color .15s;
  user-select:none;-webkit-user-select:none;
}
.nowout[data-day="0"] .nowfc > summary{background:#0c1622d9}
/* Safari puts its own triangle on a summary and this is the only way off it */
.nowfc > summary::-webkit-details-marker{display:none}
.nowfc > summary:hover,.nowfc > summary:focus-visible{background:#eef1eff2}
.nowout[data-day="0"] .nowfc > summary:hover,
.nowout[data-day="0"] .nowfc > summary:focus-visible{background:#0c1622f2}
.nowfc-chev{
  width:1.15rem;height:1.15rem;background:currentColor;
  transition:transform .25s cubic-bezier(.4,0,.2,1);
  -webkit-mask:var(--chev) center/contain no-repeat;
  mask:var(--chev) center/contain no-repeat;
  --chev:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 9 7 7 7-7'/%3E%3C/svg%3E");
}
.nowfc[open] .nowfc-chev{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){.nowfc-chev{transition:none}}

/* left:0;right:0 anchors to the nearest positioned ancestor, and that is
   .nowout-in (the centred, 1160px-max .wrap) now, not .nowout -- see the
   note above .nowout-photo. Full-bleed by width and a horizontal transform
   instead, which reaches .nowout's actual edges regardless of which
   ancestor ends up positioned.
   No CSS animation here any more, and no opacity: a fade is see-through
   for the length of the transition, which put the hero text underneath
   showing through the panel while it opened. system.js drives a real
   drawer instead -- height animated from 0 with overflow:hidden clipping
   it, so the panel is opaque throughout and looks like it slides rather
   than materializes. height:0 is the closed state so there is never a
   flash of full-height content before JS measures it on first open. */
.nowfc-panel{
  position:absolute;left:50%;top:100%;width:100vw;z-index:1;
  transform:translateX(-50%);
  height:0;overflow:hidden;
  background:var(--paper-2);color:var(--ink);
  border-bottom:1px solid var(--line);
  box-shadow:0 14px 24px -18px #0a0f1459;
}
/* With no script this is the entire show: native <details> toggles height
   between 0 and auto and nothing animates, same as before this session.
   With script, system.js sets an explicit inline pixel height for the
   length of the animation and clears it on finish -- an inline height wins
   over this rule by specificity while the animation owns the value, then
   this takes back over for anything that changes the panel's natural
   height afterwards (a window resize, a font load). */
.nowfc[open] .nowfc-panel{height:auto}
.nowfc-wrap{padding:.9rem 0}
.nowfc-days{
  display:grid;grid-template-columns:repeat(5,1fr);gap:.6rem;
  margin:0;padding:0;list-style:none;font-variant-numeric:tabular-nums;
}
.nowfc-days li{
  display:grid;justify-items:center;gap:.25rem;text-align:center;
  padding:.15rem .3rem;
}
.nowfc-days li+li{border-left:1px solid var(--line)}
/* .nowfc-when is the shared small-caps label, up with .field */
.nowfc-say{font-size:var(--t-s);color:var(--ink-soft)}
.nowfc-hi{font-family:var(--disp);font-weight:800;font-size:var(--t-m);line-height:1}
.nowfc-lo{font-size:var(--t-s);color:var(--ink-soft)}
.nowfc-days .nowout-sky{width:1.6rem;height:1.6rem}

.nowout-sky{
  width:1.5rem;height:1.5rem;flex:none;align-self:center;
  background:currentColor;
  -webkit-mask:var(--sky) center/contain no-repeat;
  mask:var(--sky) center/contain no-repeat;
}
.nowout-sun{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4.4'/%3E%3Cpath d='M12 2.2v2.4M12 19.4v2.4M2.2 12h2.4M19.4 12h2.4M5.1 5.1l1.7 1.7M17.2 17.2l1.7 1.7M18.9 5.1l-1.7 1.7M6.8 17.2l-1.7 1.7'/%3E%3C/svg%3E")}
/* a clear sky after dark. Same box, same stroke, so it swaps for the sun
   without the band changing height by a pixel. */
.nowout-moon{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.4 14.6A8.8 8.8 0 0 1 9.4 3.6a8.8 8.8 0 1 0 11 11Z'/%3E%3C/svg%3E")}
.nowout-cloud{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.6 18.5h10.6a3.9 3.9 0 0 0 .5-7.77 5.6 5.6 0 0 0-10.7-1.4 4.6 4.6 0 0 0-.4 9.17Z'/%3E%3C/svg%3E")}
.nowout-rain{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.8 15.2h10.4a3.7 3.7 0 0 0 .4-7.4 5.4 5.4 0 0 0-10.3-1.3 4.4 4.4 0 0 0-.5 8.7Z'/%3E%3Cpath d='M8.6 18.4l-1 2.6M12.4 18.4l-1 2.6M16.2 18.4l-1 2.6'/%3E%3C/svg%3E")}
.nowout-snow{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.8 15.2h10.4a3.7 3.7 0 0 0 .4-7.4 5.4 5.4 0 0 0-10.3-1.3 4.4 4.4 0 0 0-.5 8.7Z'/%3E%3Cpath d='M8.4 19.4h.01M12 19.4h.01M15.6 19.4h.01M10.2 21.6h.01M13.8 21.6h.01'/%3E%3C/svg%3E")}
.nowout-fog{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.8 13.4h10.4a3.7 3.7 0 0 0 .4-7.4 5.4 5.4 0 0 0-10.3-1.3 4.4 4.4 0 0 0-.5 8.7Z'/%3E%3Cpath d='M4.4 17h15.2M6.8 20.2h10.4'/%3E%3C/svg%3E")}
.nowout-storm{--sky:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.8 14.6h10.4a3.7 3.7 0 0 0 .4-7.4 5.4 5.4 0 0 0-10.3-1.3 4.4 4.4 0 0 0-.5 8.7Z'/%3E%3Cpath d='M13.4 17.2l-2.8 3.4h3l-2.2 2.6'/%3E%3C/svg%3E")}
