/* ═══════════════════════════════════════════════════════════════════════════
   HOME: the launcher
   ═══════════════════════════════════════════════════════════════════════════

   A channel menu, in the Wii sense: a small number of large, calm targets,
   each one carrying a real number rather than only an icon. The map tile is a
   live map; the cheapest-pint tile is the actual cheapest pint near you.

   The rule that keeps this from being a wasted tap: every tile must either
   answer a question on its face, or be a destination you would have navigated
   to anyway. A tile that only says "Map" would fail that test.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The pin tokens now live in shared.css so map.html gets them too. */
:root{ --brass:var(--brass-400,#D4A44C); }

body.home{
  min-height:100dvh;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-sans);
  display:flex;flex-direction:column;
  overflow-x:hidden;
}

/* ── Top bar ──────────────────────────────────────────────────────────────
   Deliberately not navigation. Identity on the left, you on the right; the
   tiles are the only way through. */
.home-top{
  display:flex;align-items:center;gap:var(--s-3);
  /* In flow rather than fixed, so this cannot inherit --header-h the way the
     other pages do, but it is the top of the first screen a stranger sees,
     and on a home screen it sits behind the clock without this. */
  padding:calc(14px + env(safe-area-inset-top)) 18px 12px;
  flex-shrink:0;
  /* mountAccountMenu() appends the menu inside this header and positions it
     absolutely. Without a containing block here it resolves against the
     initial one, and `top: calc(100% + 6px)` then means the bottom of the
     viewport rather than the bottom of the header. */
  position:relative;
}
.home-brand{display:flex;align-items:center;gap:11px;min-width:0}
.home-brand-text{min-width:0}
.home-brand h1{
  font-family:var(--font-display);
  font-size:var(--t-xl);font-weight:700;letter-spacing:-.015em;
  color:var(--text);line-height:1.1;
}
.home-brand h1 sup{
  font-family:var(--font-sans);font-size:12px;font-weight:400;
  vertical-align:super;color:var(--text-3);letter-spacing:0;
}
.home-brand p{
  font-size:var(--t-xs);color:var(--text-3);font-weight:400;
  margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

.home-top-right{display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0}
.home-icon-btn{
  width:38px;height:38px;border-radius:var(--r-md);
  background:var(--panel-2);border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;
  font-size:15px;color:var(--text-2);
  cursor:pointer;text-decoration:none;
  transition:background var(--dur-fast) ease,border-color var(--dur-fast) ease;
}
.home-icon-btn:hover{background:var(--hover);border-color:var(--border-strong)}
.home-avatar-btn{
  border-radius:50%;overflow:hidden;
  background:var(--accent-solid);border-color:var(--accent-solid);
  color:var(--on-accent);font-weight:700;font-size:14px;
}
.home-avatar-btn img{width:100%;height:100%;object-fit:cover}

/* ── Layout ── */
.home-main{
  flex:1;
  width:100%;max-width:1120px;margin:0 auto;
  /* The bottom nav's clearance comes from body:has(.tabbar) in shared.css, so
     this only needs enough to breathe above it. */
  padding:14px 18px 14px;
  display:flex;flex-direction:column;gap:11px;
}

/* ── Tiles ────────────────────────────────────────────────────────────────
   One shared surface. Colour is carried by the icon and the number, not by
   six competing tile backgrounds, the mistake the old toolbar made. */
.tile{
  position:relative;
  display:flex;flex-direction:column;
  padding:13px 15px 14px;
  min-height:96px;
  background:var(--panel);
  border:1px solid var(--border);
  border-radius:var(--r-xl,20px);
  color:var(--text);text-decoration:none;
  text-align:left;
  overflow:hidden;
  isolation:isolate;
  transition:transform var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) ease,
             box-shadow var(--dur-fast) ease;
}
.tile:hover{
  transform:translateY(-2px);
  border-color:var(--border-strong);
  box-shadow:var(--shadow-2);
}
.tile:active{transform:translateY(0) scale(.985)}
.tile:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* ── The tile head ────────────────────────────────────────────────────────
   Icon and number on one line. Stacked, the number needed its own 14px of
   margin and a 34px line of its own, and every tile carried 126px of height
   to say one thing, which put the bottom two rows of the menu below the fold
   on a phone. Side by side they cost one line between them, the tiles lose
   30px each, and the whole launcher fits on one screen with nothing to
   scroll to. */
.tile-head{
  display:flex;align-items:center;gap:9px;
  margin-bottom:8px;min-height:30px;
}
.tile-ico{font-size:21px;line-height:1;flex-shrink:0}
.tile-eyebrow{
  font-size:var(--t-2xs);font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--brass);
  margin-bottom:4px;
}
.tile-stat{
  font-family:var(--font-num);
  font-size:clamp(22px,5.4vw,28px);font-weight:700;line-height:1;
  color:var(--accent);
  font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.tile-stat[hidden]{display:none}
.tile-title{font-size:var(--t-base);font-weight:700;letter-spacing:-.01em}
.tile-sub{
  font-size:var(--t-xs);color:var(--text-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
}

/* Passport progress */
.tile-bar{
  margin-top:10px;height:4px;border-radius:999px;
  background:var(--panel-2);border:1px solid var(--border);
  overflow:hidden;
}
.tile-bar span{
  display:block;height:100%;width:0;
  background:var(--accent-solid);border-radius:999px;
  transition:width .6s var(--ease-out);
}

/* ── The map channel ──────────────────────────────────────────────────────
   Full width, taller, and showing real geography. This is the front door and
   it should look like the product, not like a button. */
.tile-map{
  min-height:210px;
  padding:0;
  justify-content:flex-end;
}
.tile-map-canvas{
  position:absolute;inset:0;z-index:0;
  background:var(--panel-2);
  /* Leaflet inside a link: kill every interaction so the tile stays one target */
  pointer-events:none;
}
.tile-map-canvas .leaflet-container{background:var(--panel-2)}
/* Legibility floor for the text sitting over live map tiles, which can be any
   colour depending on what is underneath. */
.tile-map-veil{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to top,
    var(--panel) 0%,
    color-mix(in srgb, var(--panel) 82%, transparent) 34%,
    transparent 72%);
}
.tile-map-body{position:relative;z-index:2;padding:16px 18px 17px}
.tile-map .tile-title{font-family:var(--font-display);font-size:var(--t-lg)}
.tile-go{
  position:absolute;top:14px;right:16px;z-index:2;
  width:34px;height:34px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-solid);color:var(--on-accent);
  font-size:15px;font-weight:700;
  box-shadow:var(--shadow-2);
  transition:transform var(--dur-fast) var(--ease-out);
}
.tile-map:hover .tile-go{transform:translateX(3px)}

/* Pins in the preview: small, quiet, and clearly not tappable. */
.home-pin span{
  display:block;width:9px;height:9px;border-radius:50%;
  background:var(--accent-solid);
  border:1.5px solid color-mix(in srgb, var(--panel) 80%, transparent);
  box-shadow:0 1px 3px rgba(0,0,0,.45);
}
.home-me span{
  display:block;width:14px;height:14px;border-radius:50%;
  background:var(--info,#38bdf8);
  border:2.5px solid var(--panel);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--info,#38bdf8) 26%, transparent);
}

/* ── Grid ─────────────────────────────────────────────────────────────────
   Two columns on a phone. Anything narrower than a 150px tile stops being
   readable, so below 360px it drops to one. */
.tile-grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px;
}
@media (max-width:359px){ .tile-grid{grid-template-columns:1fr} }

/* ── Fitting the phone ────────────────────────────────────────────────────
   The launcher is a menu. A menu you have to scroll to see the bottom of is
   a menu with a hidden half, and the two tiles that fell off the end were
   Chat and Feeling lucky, the two nobody would think to look for.

   Measured against a 390×844 viewport with the bottom nav in place: the seven
   tiles, the map channel and the header have about 700px to live in. These
   are the numbers that make them. The knot rule and the footer links are
   deliberately allowed below the fold; they are chrome, not menu. */
@media (max-width:600px) and (min-height:640px){
  .tile{min-height:86px;padding:11px 13px 12px}
  /* Whatever the tiles leave, the map channel takes. It is the front door and
     it should look like the product rather than like a button.
     .tile.tile-map, not .tile-map: the map tile carries both classes, and a
     bare .tile-map ties with the .tile rule above on specificity, which the
     later declaration then wins, collapsing the map to a letterbox. */
  .tile.tile-map{min-height:248px}
  .tile-head{margin-bottom:6px;min-height:28px}
  .tile-grid{gap:10px}
  .home-main{gap:10px;padding:11px 14px 10px}
  /* Tighter, but the status-bar inset survives the tightening, dropping it
     here is how a small phone ends up being the one device the header sits
     under the clock on. */
  .home-top{padding:calc(10px + env(safe-area-inset-top)) 14px 9px}
}

/* Colour comes from the numbers, and only where it means something. */
.tile-cheap  .tile-stat{color:var(--accent)}
.tile-tonight .tile-stat{color:var(--brass)}
.tile-passport .tile-stat,
.tile-chat .tile-stat,
.tile-explore .tile-stat{color:var(--text)}

/* A tile that is a <button> has to be told it is not a button. */
.tile-crawl{
  font-family:var(--font-sans);
  appearance:none;-webkit-appearance:none;
  width:100%;
}

/* An odd number of tiles in a two-column grid leaves one on a row of its own.
   Rather than a half-empty row at the end, the last one goes wide and lies
   down: icon, title and line on a single row. It reads as a footer to the
   menu, which is what "let PinPint pick" actually is.

   Scoped to :last-child rather than to Lucky itself, which is what it used to
   be. With Your listings added the grid is eight and even, Lucky is no longer
   last, and hardcoding the wide treatment to that one tile would have left a
   full-width Lucky above a half-width orphan, the exact shape this rule was
   written to prevent, produced by the rule itself. */
.tile-grid .tile:last-child:nth-child(odd){
  grid-column:1 / -1;
  flex-direction:row;align-items:center;gap:11px;
  min-height:0;padding:11px 15px;
}
.tile-grid .tile:last-child:nth-child(odd) .tile-head{margin:0;min-height:0}
.tile-grid .tile:last-child:nth-child(odd) .tile-title{flex-shrink:0}
.tile-grid .tile:last-child:nth-child(odd) .tile-sub{margin-top:0;-webkit-line-clamp:1}

/* ── Footer ── */
.home-foot{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:8px;padding:6px 0 0;
  font-size:var(--t-xs);color:var(--text-3);
}
.home-foot a{color:var(--text-3);text-decoration:none}
.home-foot a:hover{color:var(--text-2);text-decoration:underline}

/* ── Desktop ──────────────────────────────────────────────────────────────
   The map channel takes the left half and full height; the rest stack beside
   it. Same information, no scrolling, no stranded column.

   THE ROW THAT GROWS
   ------------------
   `grid-template-rows: auto auto` with `align-content: start` was the whole
   launcher sitting at the top of the window and a band of empty ground under
   it: 150px on a 1024 laptop, 280px on a 1440 one, between the footer links
   and the nav. It read as a page that had finished loading half of itself.

   The content row is `minmax(0, 1fr)` now, so the map and the tiles take
   whatever height is going, and the knot and the footer sit under them at
   their own height. minmax(0, …) rather than a bare 1fr because a grid row's
   default minimum is its content, and the map inside it is a min-height:
   without the 0 the row can only grow and the tall-window case wins over the
   short one. */
@media (min-width:820px){
  .home-main{
    display:grid;
    grid-template-columns:1.15fr 1fr;
    grid-template-rows:minmax(0,1fr) auto auto;
    gap:14px;
    padding:18px 24px 24px;
    align-content:stretch;
  }
  .tile-map{grid-row:1;min-height:420px}
  .tile-grid{grid-row:1;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-content:start}
  .knot-rule{grid-column:1 / -1;grid-row:2}
  .home-foot{grid-column:1 / -1;grid-row:3}
  .tile{min-height:112px}
}

/* Three columns of tiles need the width for three columns of tiles. At 1180
   the container was still capped at 1120px and the map was taking the larger
   share of it, which left each tile about 150px wide: "Chat with friends"
   wrapped onto two lines with white space on every side of it. The cap moves
   up and the split evens out, and the tiles get the room the third column
   was supposed to buy them. */
@media (min-width:1180px){
  .home-main,
  .home-top{max-width:1280px;margin-inline:auto;width:100%}
  .home-main{grid-template-columns:1fr 1.22fr}
  .tile-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .tile-map{min-height:470px}
}

/* ── Very wide ────────────────────────────────────────────────────────────
   A launcher is a menu, and a menu stretched across a 2560px monitor is a
   row of buttons with a metre between them. It stops growing and centres. */
@media (min-width:1500px){
  .home-main,
  .home-top{max-width:1400px}
  .tile-map{min-height:520px}
}

/* ── A short window ───────────────────────────────────────────────────────
   A laptop at 1440×720, or any desktop browser carrying a bookmarks bar and
   an open console, has less vertical room than a phone. The map's min-height
   alone was most of it and the tiles went under the nav.

   Only the minimums come down. The row above still stretches, because
   `.home-main` is `flex:1` inside a `min-height:100dvh` column and therefore
   has a real height to divide: the fill is what closes the gap, and the caps
   here are only what stops the map from asking for more than there is.

   Last on purpose. Every block above raises the map's minimum as the screen
   gets wider, and all of them match a wide short window too. Specificity is
   equal, so source order decides, and this has to be the one that answers.
   Moving it up the file is the kind of edit that looks tidy and quietly puts
   the launcher back through the floor. */
@media (min-width:820px) and (max-height:820px){
  .home-main{padding-bottom:14px}
  .tile-map{min-height:min(340px, 42vh)}
  .tile{min-height:96px}
}

/* ── Entrance ─────────────────────────────────────────────────────────────
   A short stagger so the menu assembles rather than appearing. Kept under
   400ms total: this is the first screen, and it must not feel slow. */
@keyframes home-tile-in{
  from{opacity:0;transform:translateY(10px)}
  to{opacity:1;transform:none}
}
.tile{animation:home-tile-in .34s var(--ease-out) both}
.tile-map{animation-delay:.02s}
.tile-grid .tile:nth-child(1){animation-delay:.07s}
.tile-grid .tile:nth-child(2){animation-delay:.11s}
.tile-grid .tile:nth-child(3){animation-delay:.15s}
.tile-grid .tile:nth-child(4){animation-delay:.19s}
.tile-grid .tile:nth-child(5){animation-delay:.23s}
.tile-grid .tile:nth-child(6){animation-delay:.27s}
.tile-grid .tile:nth-child(7){animation-delay:.31s}
.tile-grid .tile:nth-child(8){animation-delay:.35s}

@media (prefers-reduced-motion:reduce){
  .tile{animation:none;transition:none}
  .tile:hover{transform:none}
  .tile-bar span{transition:none}
}

/* Keyboard users get a way past the tiles without tabbing the map link. */
/* .skip-link moved to shared.css, the map has one now too, and a rule that
   only exists in the launcher's stylesheet is a rule the map cannot use. */

/* Logged out, the avatar is a generic person glyph, not initials, a green
   circle with "?" in it reads like an error. */
.home-avatar-btn.is-guest{
  background:var(--panel-2);border-color:var(--border);
  color:var(--text-3);font-size:15px;
}
.home-avatar-btn.is-guest:hover{background:var(--hover);border-color:var(--border-strong)}
.tile-bar[hidden]{display:none}

/* ═══════════════════════════════════════════════════════════════════════════
   FIRST RUN
   Shown once, on the launcher, before anything else has a chance to confuse.
   Deliberately not a carousel: three points on one card, both buttons dismiss,
   and Escape works. Nobody should have to earn their way into a pub app.
   ═══════════════════════════════════════════════════════════════════════════ */
.ob{
  position:fixed;inset:0;z-index:var(--z-dialog);
  display:flex;align-items:center;justify-content:center;
  padding:20px;
  background:color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);
  animation:ob-fade .22s ease both;
}
.ob[hidden]{display:none}
@keyframes ob-fade{from{opacity:0}to{opacity:1}}

.ob-card{
  width:100%;max-width:430px;
  max-height:calc(100dvh - 40px);overflow-y:auto;
  padding:26px 24px 20px;
  background:var(--panel);
  border:1px solid var(--border);
  border-radius:var(--r-xl,20px);
  box-shadow:var(--shadow-3,0 18px 50px rgba(0,0,0,.5));
  animation:ob-rise .3s var(--ease-out) both;
}
@keyframes ob-rise{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}

.ob-crest{
  width:52px;height:52px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:25px;margin-bottom:14px;
  background:var(--brand-ghost);
  border:1px solid var(--accent);
}
.ob-title{
  font-family:var(--font-display);
  font-size:clamp(20px,5vw,25px);font-weight:700;line-height:1.2;
  letter-spacing:-.015em;color:var(--text);
}
.ob-lede{
  font-size:var(--t-sm);color:var(--text-2);
  margin-top:8px;line-height:1.5;
}

.ob-points{list-style:none;margin:20px 0 22px;padding:0;display:flex;flex-direction:column;gap:15px}
.ob-points li{display:flex;gap:12px;align-items:flex-start}
.ob-point-ico{
  flex-shrink:0;width:30px;height:30px;border-radius:var(--r-sm);
  display:flex;align-items:center;justify-content:center;font-size:15px;
  background:var(--panel-2);border:1px solid var(--border);
}
.ob-points strong{display:block;font-size:var(--t-base);font-weight:700;color:var(--text)}
.ob-points span{display:block;font-size:var(--t-xs);color:var(--text-3);line-height:1.5;margin-top:2px}

/* Show the colours rather than describing them, this is the one thing the
   product cannot explain in words. */
.ob-swatches{display:flex!important;gap:6px;margin-top:8px}
.ob-sw{
  font-family:var(--font-num);
  font-size:13px;font-weight:700;
  padding:3px 8px;border-radius:var(--r-full);
  font-variant-numeric:tabular-nums;
}
.ob-sw-cheap{background:var(--price-cheap);color:var(--price-cheap-ink);border:1px solid var(--price-cheap-edge)}
.ob-sw-mid  {background:var(--price-mid);  color:var(--price-mid-ink);  border:1px solid var(--price-mid-edge)}
.ob-sw-dear {background:var(--price-dear); color:var(--price-dear-ink); border:1px solid var(--price-dear-edge)}

.ob-go{
  width:100%;min-height:46px;padding:12px 18px;
  background:var(--accent-solid);border:1px solid var(--accent-solid);
  border-radius:var(--r-full);color:var(--on-accent);
  font-family:var(--font-sans);font-size:var(--t-base);font-weight:700;
  cursor:pointer;
  transition:background var(--dur-fast) ease,transform var(--dur-fast) var(--ease-out);
}
.ob-go:hover{background:var(--brand-500)}
.ob-go:active{transform:scale(.98)}
.ob-skip{
  display:block;width:100%;margin-top:6px;padding:9px;
  background:none;border:none;cursor:pointer;
  color:var(--text-3);font-family:var(--font-sans);font-size:var(--t-xs);
}
.ob-skip:hover{color:var(--text-2);text-decoration:underline}

@media (prefers-reduced-motion:reduce){
  .ob,.ob-card{animation:none}
  .ob-go:active{transform:none}
}

/* The logo in the launcher header. A raster mark, so it is given an explicit
   box and a radius that matches the tile inside it: a 192px icon drawn at 34
   without a radius shows the PNG's own corners against the header. */
.home-brand-mark{
  width:34px;height:34px;flex-shrink:0;
  border-radius:9px;
  display:block;
}
