/* Whereto — Cobalt Editorial (brand guide v2.0)
   White does the heavy lifting; cobalt is punctuation, not wallpaper.
   No gradients, no dark grounds, no red, no star ratings. */

:root{
  --cobalt:#1238a6; --blue:#2f63d8; --softsky:#86bdf2; --sun:#fff59d;
  --sky:#c5e5ff; --coral:#c1ddff; --lilac:#e2ebff; --mist:#f1f7ff;
  --ink:#151a26; --muted:#435066; --hairline:#c2d3e8;
  --radius:12px;

  /* The built-in CSS easings are too weak to read as intentional. These are
     the stronger variants: ease-out for anything entering or responding to a
     press, ease-in-out for things moving on screen. ease-in is never used -
     it delays the first few frames, which is exactly when the eye is on it. */
  --ease-out:cubic-bezier(.23,1,.32,1);
  --ease-in-out:cubic-bezier(.77,0,.175,1);
  --measure:62ch;
  --gutter:clamp(20px,5vw,40px);
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:"DM Sans",system-ui,-apple-system,sans-serif;
  color:var(--ink);background:#fff;line-height:1.6;
  font-synthesis-weight:none;
}
img{max-width:100%;display:block}
a{color:var(--cobalt);text-decoration:none}
a{transition:color 140ms ease}
@media (hover:hover) and (pointer:fine){
  a:hover{color:var(--blue);text-decoration:underline;text-underline-offset:3px}
}

/* Nothing had a focus indicator, so keyboard users had no position on a page
   with 43 links. :focus-visible keeps it off mouse clicks. */
:focus-visible{
  outline:3px solid var(--cobalt);outline-offset:3px;border-radius:4px;
}
.site-footer :focus-visible{outline-color:var(--sun)}

.serif,h1,h2,h3{font-family:"DM Serif Display",Georgia,"Times New Roman",serif;font-weight:400;letter-spacing:0}
h1{font-size:clamp(34px,6vw,60px);line-height:1.06}
h2{font-size:clamp(26px,3.4vw,38px);line-height:1.15}
h3{font-size:19px;line-height:1.25}

.wrap{max-width:1080px;margin:0 auto;padding:0 var(--gutter)}
.wrap--narrow{max-width:760px}

/* Eyebrow — category labels and kickers only */
.eyebrow{
  display:inline-block;font-size:12px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cobalt);
}
.lede{color:var(--muted);max-width:var(--measure);font-size:17px}

/* ---------- masthead ---------- */
.masthead{border-bottom:1px solid var(--hairline);background:#fff;position:sticky;top:0;z-index:20}
.masthead__inner{display:flex;align-items:center;gap:24px;padding:8px 0;flex-wrap:wrap}
.wordmark{
  font-family:"DM Serif Display",Georgia,serif;font-size:26px;line-height:1;
  color:var(--ink);letter-spacing:-.01em;
  display:inline-flex;align-items:center;min-height:44px;
}
.wordmark .dot{color:var(--cobalt)}
.masthead nav{display:flex;gap:18px;flex-wrap:wrap;margin-left:auto}
/* 44px minimum touch target. Every link on the page failed this. */
.masthead nav a{
  font-size:14px;font-weight:500;color:var(--muted);
  display:inline-flex;align-items:center;min-height:44px;
}
/* Used on every visit, several times. Colour only - movement here would be
   noticed as friction rather than polish. */
.masthead nav a[aria-current="page"]{color:var(--cobalt);text-decoration:none}
@media (hover:hover) and (pointer:fine){
  .masthead nav a:hover{color:var(--cobalt);text-decoration:none}
}

/* ---------- hero ---------- */
.hero{padding:clamp(48px,8vw,96px) 0 clamp(40px,6vw,72px)}
.hero h1{max-width:16ch}
.hero .lede{margin-top:18px;font-size:19px}
.hero__meta{display:flex;gap:10px;flex-wrap:wrap;margin-top:28px}

.chip{
  display:inline-block;background:var(--mist);border:1px solid var(--hairline);
  border-radius:999px;padding:6px 14px;font-size:13px;font-weight:500;color:var(--muted);
}
.chip--solid{background:var(--cobalt);border-color:var(--cobalt);color:#fff}

/* ---------- city hero band ---------- */
.band{border-radius:var(--radius);padding:clamp(28px,5vw,52px);margin-bottom:40px}
.band--sky{background:var(--sky)}
.band--lilac{background:var(--lilac)}
.band--sun{background:var(--sun)}
.band--mist{background:var(--mist)}
.band h1{margin-top:6px}
.band .lede{margin-top:12px;color:var(--ink);opacity:.72}

/* ---------- category nav ---------- */
.catnav{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 28px}
.catnav a{
  border:1px solid var(--hairline);border-radius:999px;padding:0 20px;
  font-size:13px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  display:inline-flex;align-items:center;min-height:44px;
}
.catnav a{transition:border-color 160ms ease,color 160ms ease,transform 160ms var(--ease-out)}
.catnav a:active{transform:scale(.97)}
@media (hover:hover) and (pointer:fine){
  .catnav a:hover{border-color:var(--cobalt);color:var(--cobalt);text-decoration:none}
}
.catnav a.is-active{background:var(--cobalt);border-color:var(--cobalt);color:#fff}

/* ---------- section head ---------- */
.sectionhead{margin:clamp(40px,6vw,72px) 0 24px}
.sectionhead h2{margin-top:6px}
.sectionhead p{color:var(--muted);margin-top:8px;max-width:var(--measure)}

/* ---------- place grid ---------- */
.grid{display:grid;gap:24px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}

.card{border:1px solid var(--hairline);border-radius:var(--radius);overflow:hidden;
  background:#fff;display:flex;flex-direction:column;
  transition:border-color 200ms ease,box-shadow 200ms ease,transform 200ms var(--ease-out)}
@media (hover:hover) and (pointer:fine){
  .card:hover{border-color:#aebfd8;box-shadow:0 8px 28px rgba(18,56,166,.08);transform:translateY(-2px)}
  /* the photograph breathes a little under the card's own overflow:hidden */
  .card:hover .card__media img{transform:scale(1.03)}
}
.card__media img{transition:transform 420ms var(--ease-out)}
.card__media{
  position:relative;aspect-ratio:4/3;display:grid;place-items:center;
  border-bottom:1px solid var(--hairline);overflow:hidden;
}
/* Placeholder plate — stands in until real photography exists.
   Brand is photo-first; this is explicitly a stopgap, not the design. */
.card__initial{font-family:"DM Serif Display",Georgia,serif;font-size:64px;color:#fff;opacity:.9;line-height:1}
.card__rank{
  position:absolute;top:12px;left:12px;background:#fff;color:var(--cobalt);
  border-radius:999px;min-width:30px;height:30px;display:grid;place-items:center;
  font-size:14px;font-weight:700;padding:0 9px;
}
.card__body{padding:18px 18px 20px;display:flex;flex-direction:column;gap:6px;flex:1}
.card__name{font-family:"DM Serif Display",Georgia,serif;font-size:22px;line-height:1.2}
.card__where{font-size:13px;color:var(--muted)}
.card__why{font-size:15px;color:var(--ink);margin-top:2px}
.card__why--missing{color:var(--muted);font-style:italic}
.card__foot{margin-top:auto;padding-top:8px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.tag{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--blue);
  display:inline-flex;align-items:center;min-height:44px}
.tag--quiet{color:var(--muted)}

/* ---------- city index ---------- */
.citygrid{display:grid;gap:20px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.citycard{
  border:1px solid var(--hairline);border-radius:var(--radius);padding:24px;
  display:flex;flex-direction:column;gap:6px;background:#fff;color:inherit;
}
.citycard{transition:border-color 180ms ease,transform 180ms var(--ease-out),box-shadow 180ms ease}
.citycard:active{transform:scale(.99)}
@media (hover:hover) and (pointer:fine){
  .citycard:hover{border-color:var(--cobalt);text-decoration:none;
    transform:translateY(-2px);box-shadow:0 6px 20px rgba(18,56,166,.10)}
}
.citycard h3{font-size:26px}
.citycard .count{font-size:13px;color:var(--muted)}

/* ---------- notes / callouts ---------- */
.note{
  border:1px solid var(--hairline);border-left:3px solid var(--cobalt);
  border-radius:var(--radius);padding:18px 20px;background:var(--mist);
  font-size:15px;color:var(--muted);max-width:var(--measure);
}

/* ---------- footer ---------- */
.site-footer{background:var(--cobalt);color:#fff;margin-top:clamp(56px,8vw,96px);padding:48px 0 40px}
.site-footer .wordmark{color:#fff}
.site-footer .wordmark .dot{color:var(--sun)}
.site-footer p{opacity:.85;margin-top:8px}
.site-footer nav{display:flex;gap:16px;flex-wrap:wrap;margin-top:20px}
.site-footer a{color:#fff;opacity:.85;font-size:14px;
  display:inline-flex;align-items:center;min-height:44px}
.site-footer a:hover{opacity:1}
.site-footer .fine{margin-top:26px;font-size:13px;opacity:.6}

/* ---------- responsive ---------- */
/* ---------- mobile ---------- */
@media (max-width:560px){
  /* The page ran to 18.2 viewports for 20 cards, with a median card of 660px -
     taller than the 812px screen it sits on. Three things were spending that
     height: a 4:3 image, an unbounded highlight block that reached 272px (40%
     of a card), and desktop padding throughout. */

  /* 4:3 -> 16:10. Still generous for a photo, 60px cheaper per card. */
  .card__media{aspect-ratio:16/10}

  /* Cap the Google summary at four lines. These are repetitive by nature
     ("Diners like... They also highlight..."), so the substance is in the
     opening lines. The full text stays in the DOM for screen readers and
     search engines; only the visual run is clipped. Desktop shows all of it. */
  .card__highlight{
    display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;
    overflow:hidden;padding:10px 12px;font-size:13.5px;
  }

  .card__body{padding:14px 14px 16px;gap:5px}
  .card__name{font-size:20px}
  .grid{gap:18px}
  .sectionhead{margin:32px 0 18px}
  .band{padding:22px;margin-bottom:28px}
  .catnav{margin-bottom:22px}
  /* The city list wrapped to four lines - a 186px sticky masthead, 23% of an
     812px phone screen, pushing the first card 587px down the page. One
     scrollable row instead. No JS: the nav is just an overflow container. */
  .masthead__inner{gap:12px;padding:4px 0}
  .masthead nav{
    width:100%;margin-left:0;flex-wrap:nowrap;overflow-x:auto;
    gap:14px;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    /* Hint the edge only. At 85% the fade was washing out city names that
       were perfectly readable, which looked like a rendering fault. */
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
  }
  .masthead nav::-webkit-scrollbar{display:none}
  .masthead nav a{white-space:nowrap}
  .grid{grid-template-columns:1fr}
}

/* photo cards — image replaces the placeholder plate */
/* Absolute, not just height:100% — the image's own aspect ratio otherwise wins
   over the container's and a portrait photo stretches its whole card taller
   than the rest of the row. */
.card__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.card__credit{
  position:absolute;right:10px;bottom:8px;font-size:10px;color:#fff;
  background:rgba(21,26,38,.55);border-radius:999px;padding:3px 8px;
  max-width:72%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* rating / price / type line */
.card__meta{display:flex;gap:10px;flex-wrap:wrap;align-items:baseline;font-size:13px;color:var(--muted)}
.meta__rating{font-weight:700;color:var(--ink)}
.meta__count{font-weight:400;color:var(--muted)}
.meta__price{color:var(--cobalt);font-weight:700}
.meta__type{color:var(--muted)}

/* highlights from Google, with the disclosure attached */
.card__highlight{font-size:14px;color:var(--muted);background:var(--mist);
  border-radius:10px;padding:12px 14px;margin-top:4px}
.card__disclosure{display:block;margin-top:6px;font-size:11px;color:var(--muted);opacity:.75}

/* ---------- near you ---------- */
.nearform{border:1px solid var(--hairline);border-radius:var(--radius);padding:22px;background:var(--mist)}
.nearform__label{display:block;font-size:13px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--cobalt);margin-bottom:10px}
.nearform__row{display:flex;gap:10px;flex-wrap:wrap}
.nearform input{flex:1 1 220px;min-height:48px;padding:0 16px;font:inherit;font-size:16px;
  border:1px solid var(--hairline);border-radius:10px;background:#fff;color:var(--ink)}
.nearform input:focus-visible{outline:3px solid var(--cobalt);outline-offset:2px}
.btn{min-height:48px;padding:0 22px;border:1px solid var(--cobalt);border-radius:10px;
  background:var(--cobalt);color:#fff;font:inherit;font-weight:700;font-size:15px;cursor:pointer}
/* 160ms scale on press. Without it the button gives no sign it was heard. */
.btn{transition:background-color 160ms ease,border-color 160ms ease,
     transform 160ms var(--ease-out)}
.btn:active{transform:scale(.97)}
@media (hover:hover) and (pointer:fine){
  .btn:hover{background:var(--blue);border-color:var(--blue)}
}
.btn--quiet{background:#fff;color:var(--cobalt);margin-top:12px}
@media (hover:hover) and (pointer:fine){
  .btn--quiet:hover{background:#fff;color:var(--blue)}
}
.nearform__note{margin-top:12px;font-size:13px;color:var(--muted)}
.meta__distance{font-weight:700;color:var(--cobalt)}
#near-results{margin-top:28px}
.masthead__near{color:var(--cobalt) !important;font-weight:700}

/* ---------- near me: map ---------- */
.nearpage{padding-bottom:40px}
.nearintro{padding:clamp(32px,6vw,64px) 0 24px}
.btn--big{min-height:56px;padding:0 28px;font-size:17px;margin-top:20px}
.nearmap{height:clamp(320px,56vh,560px);margin:28px 0 8px;border-top:1px solid var(--hairline);
  border-bottom:1px solid var(--hairline);background:var(--mist)}
.nearmap .leaflet-container{font:inherit}
.pin{background:none;border:0}
.pin__n{display:grid;place-items:center;width:34px;height:34px;border-radius:999px;
  background:var(--cobalt);color:#fff;font-weight:700;font-size:15px;
  border:2px solid #fff;box-shadow:0 1px 4px rgba(21,26,38,.35)}
.leaflet-popup-content{font-family:"DM Sans",system-ui,sans-serif;font-size:14px;line-height:1.5}
.leaflet-popup-content a{color:var(--cobalt);font-weight:700}
.card--lit{outline:3px solid var(--cobalt);outline-offset:3px}
#near-results{margin-top:24px}
/* OSM's standard style is louder than the brand; mute it so the photographs
   and the cobalt pins stay the brightest things on the page. */
.nearmap .leaflet-tile-pane{filter:saturate(.55) brightness(1.04)}

/* ---------- near me: motion ---------- */
/* The results arrive after a deliberate tap, once, so a stagger is earned
   here in a way it would not be on a page you scroll past every visit.
   40ms steps: enough to read as a cascade, not enough to wait for. */
#near-results .card{
  opacity:0;transform:translateY(10px);
  animation:card-in 320ms var(--ease-out) forwards;
}
#near-results .card:nth-child(1){animation-delay:0ms}
#near-results .card:nth-child(2){animation-delay:40ms}
#near-results .card:nth-child(3){animation-delay:80ms}
#near-results .card:nth-child(4){animation-delay:120ms}
#near-results .card:nth-child(5){animation-delay:160ms}
#near-results .card:nth-child(6){animation-delay:200ms}
#near-results .card:nth-child(7){animation-delay:240ms}
#near-results .card:nth-child(8){animation-delay:280ms}
#near-results .card:nth-child(9){animation-delay:320ms}
#near-results .card:nth-child(10){animation-delay:360ms}
@keyframes card-in{to{opacity:1;transform:translateY(0)}}

/* Pins land rather than appear. Starting at .6 rather than 0 - nothing in the
   real world arrives from nothing, and a pin popping from zero reads as a
   glitch. */
.pin__n{animation:pin-in 260ms var(--ease-out) backwards}
@keyframes pin-in{from{opacity:0;transform:scale(.6)}}
.pin{transition:transform 160ms var(--ease-out)}
@media (hover:hover) and (pointer:fine){.pin:hover{transform:scale(1.12)}}

/* A popup belongs to the pin it came from, so it grows from the pin's tip
   rather than from its own middle. */
.leaflet-popup{transform-origin:bottom center;animation:popup-in 180ms var(--ease-out)}
@keyframes popup-in{from{opacity:0;transform:scale(.96)}}

.card--lit{outline:3px solid var(--cobalt);outline-offset:3px}
.card{transition:border-color 200ms ease,box-shadow 200ms ease,
      transform 200ms var(--ease-out),outline-color 200ms ease}

/* ---------- reduced motion ---------- */
/* Fewer and gentler, not none. Opacity and colour still carry meaning; it is
   movement that causes trouble, so the transforms go and the fades stay. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important;
  }
  #near-results .card{opacity:1;transform:none;animation:none}
  .pin__n{animation:none}
  .leaflet-popup{animation:none}
  .card:hover,.citycard:hover{transform:none}
  .card:hover .card__media img{transform:none}
}
