/* 格格價 · image-led layout system (2026-09-27)
   Loaded after style.css + theme.css. Sky tokens stay the source of truth for colour, radius and type;
   this file only adds layout components: photo hero, snap rails, image tiles, listing cards, carousels,
   sticky bars and the save heart. Patterns borrowed (not assets) from Agoda, Airbnb, Tripadvisor, Expedia. */
:root{
  --scrim:10,24,52;               /* navy used for photo scrims; text on it is white */
  --tile-radius:var(--radius);
  --rail-gap:12px;
  --shimmer-a:var(--bg-2); --shimmer-b:color-mix(in srgb,var(--bg-2) 55%,var(--card));
  --heart:#d93a4a;                /* filled heart only; 4.6:1 on white chip */
  --chip-on-photo:rgba(255,255,255,.94);
}
@media (min-width:720px){:root{--rail-gap:20px}}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--heart:#ff7a86;--chip-on-photo:rgba(23,34,53,.92)}}
:root[data-theme="dark"]{--heart:#ff7a86;--chip-on-photo:rgba(23,34,53,.92)}

/* ───────── image boxes: fixed ratio, shimmer while loading, zoom on hover ───────── */
.ph-box{position:relative;overflow:hidden;background:var(--shimmer-a);aspect-ratio:var(--ar,3/2);border-radius:var(--tile-radius);isolation:isolate}
.ph-box > img,.ph-box picture img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:var(--img-dim);
  transition:transform .6s var(--ease),opacity .35s var(--ease)}
.js .ph-box > img:not(.loaded),.js .ph-box .slides img:not(.loaded){opacity:0}
.js .ph-box:has(img:not(.loaded))::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(100deg,var(--shimmer-a) 30%,var(--shimmer-b) 50%,var(--shimmer-a) 70%) 0 0/200% 100%;animation:shimmer 1.3s linear infinite}
@keyframes shimmer{to{background-position:-200% 0}}
@media (hover:hover){
  .tile:hover .ph-box > img,.lcard:hover .ph-box > img,.post-tile:hover .ph-box > img{transform:scale(1.05)}
}
/* One hover language for every clickable image card, matching the operator cards (.op / .lcard):
   lift 3px + soft shadow (+ a jade ring where the card has a visible edge) + image zoom.
   Photo-overlay tiles skip the ring: a border can't read on a full-bleed photo. Hover devices only. */
.tile,.post-lead{transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.tile .ph-box{transition:box-shadow var(--t) var(--ease)}
@media (hover:hover){
  .tile:hover{transform:translateY(-3px)}
  .tile:hover .ph-box{box-shadow:var(--shadow-2)}
  /* Inside a scroll rail the shadow must fit the rail's padding (overflow clips it): tighter, same navy tint in both themes */
  .rail .tile:hover .ph-box{box-shadow:var(--shadow-1),0 14px 24px -10px color-mix(in srgb,var(--dark) 45%,transparent)}
  .rail .tile:not(.t-overlay):hover .ph-box{box-shadow:var(--shadow-1),0 14px 24px -10px color-mix(in srgb,var(--dark) 45%,transparent),0 0 0 1px color-mix(in srgb,var(--accent) 45%,var(--line))}
  .tile:not(.t-overlay):hover .ph-box{box-shadow:var(--shadow-2),0 0 0 1px color-mix(in srgb,var(--accent) 45%,var(--line))}
  .tile:hover h3{color:var(--accent)}
  .post-lead:hover,.js .post-lead.reveal.in:hover{transform:translateY(-3px);box-shadow:var(--shadow-2)}  /* beats .js .reveal.in{transform:none} */
}
.ph-tag{position:absolute;left:10px;bottom:10px;z-index:2;font-size:12px;line-height:1;padding:6px 9px;border-radius:999px;
  background:var(--chip-on-photo);color:var(--ink);font-weight:500}

/* ───────── photo hero with floating finder (Agoda / Expedia) ───────── */
.photo-hero{position:relative;margin-bottom:var(--space-section);background:var(--bg)}
.photo-hero .hero-top{position:relative;color:#fff;overflow:hidden;background:#1d3a66}
.photo-hero .hero-top > picture img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:70% 50%;filter:var(--img-dim)}
.photo-hero .hero-top::before{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(to top,rgba(var(--scrim),.92) 0%,rgba(var(--scrim),.8) 55%,rgba(var(--scrim),.62) 100%)}
/* 格 motif: faint white grid over the photo */
.photo-hero .hero-top::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.10;
  background-image:linear-gradient(#fff 1px,transparent 1px),linear-gradient(90deg,#fff 1px,transparent 1px);background-size:44px 44px;
  -webkit-mask-image:linear-gradient(to right,#000,transparent 70%);mask-image:linear-gradient(to right,#000,transparent 70%)}
.photo-hero .hero-copy{position:relative;z-index:2;padding-top:72px;padding-bottom:76px}
.photo-hero h1{color:#fff;font-size:clamp(28px,4.6vw,52px);max-width:15em;text-wrap:balance}
.photo-hero .kicker{color:#fff}
.photo-hero .kicker .dot{background:#9cc6ff}
.photo-hero .lede{color:#e6eefb;max-width:34em}
.photo-hero mark.hl{--mark:rgba(255,255,255,.28)}
.photo-hero .hero-cap{position:absolute;z-index:2;right:12px;top:12px;font-size:12px;color:#fff;background:rgba(var(--scrim),.55);padding:4px 10px;border-radius:999px}
.photo-hero .finder-dock{position:relative;z-index:3;margin-top:-48px}
.photo-hero .finder{margin-top:0;box-shadow:var(--shadow-2),0 24px 60px rgba(var(--scrim),.18)}
@media (min-width:720px){
  .photo-hero .hero-top::before{background:linear-gradient(90deg,rgba(var(--scrim),.9) 0%,rgba(var(--scrim),.82) 45%,rgba(var(--scrim),.15) 85%)}
  .photo-hero .hero-copy{padding-top:88px;padding-bottom:104px;min-height:480px}
  .photo-hero .finder-dock{margin-top:-64px}
  .photo-hero .finder{padding:20px}
  .photo-hero .finder.hero-finder .btn{flex:0 0 auto;min-width:150px}
}
@media (min-width:1100px){.photo-hero .hero-copy{min-height:520px}}

/* ───────── sticky condensed search (built by site.js from the hero finder) ───────── */
.mini-search{position:absolute;left:0;right:0;top:100%;
  /* Same translucent surface as the header so the two read as one attached bar */
  background:color-mix(in srgb,var(--card) 95%,transparent);backdrop-filter:saturate(1.4) blur(12px);-webkit-backdrop-filter:saturate(1.4) blur(12px);
  border-top:1px solid var(--line-soft);box-shadow:var(--shadow-2);
  opacity:0;visibility:hidden;transform:translateY(-8px);transition:opacity var(--t) var(--ease),transform var(--t) var(--ease),visibility 0s linear var(--t)}
.mini-search.show{opacity:1;visibility:visible;transform:none;transition-delay:0s}
.site-header.open .mini-search{display:none}
.mini-search .wrap{display:flex;gap:10px;align-items:center;padding-top:12px;padding-bottom:16px}
/* While the mini search shows, the header hands its shadow and bottom edge to it (no grey band between) */
.site-header:has(.mini-search.show){box-shadow:none;border-bottom-color:transparent}
.mini-search select{height:44px;font-size:15px;flex:1 1 0;min-width:0}
.mini-search .btn{height:44px;padding:0 20px;flex:0 0 auto}
.mini-search .pillbtn{display:none}
@media (max-width:719px){
  .mini-search select,.mini-search .btn{display:none}
  .mini-search .pillbtn{display:flex;align-items:center;gap:10px;width:100%;min-height:48px;padding:0 16px;border-radius:999px;border:1px solid var(--field-line);
    background:var(--bg);color:var(--ink);font:inherit;font-size:15px;text-align:left;cursor:pointer;box-shadow:var(--shadow-1)}
  .mini-search .pillbtn svg{flex-shrink:0;width:18px;height:18px;stroke:var(--accent);fill:none;stroke-width:2}
  .mini-search .pillbtn span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
}


/* ───────── category icon row (Airbnb) ───────── */
.cats{display:grid;grid-auto-flow:column;grid-auto-columns:max-content;gap:8px;overflow-x:auto;scrollbar-width:none;
  margin:0 -16px;padding:4px 16px 8px;scroll-padding:0 16px;scroll-snap-type:x proximity}
.cats::-webkit-scrollbar{display:none}
@media (min-width:720px){.cats{margin:0;padding:4px 0 8px;grid-auto-columns:1fr;justify-content:stretch}}
.cat{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:84px;min-height:84px;padding:12px 10px;border-radius:var(--radius-sm);
  color:var(--ink);text-decoration:none;font-size:14.5px;font-weight:500;scroll-snap-align:start;background:var(--card);border:1px solid var(--line);
  transition:border-color var(--t-fast),transform var(--t-fast) var(--ease),box-shadow var(--t) var(--ease)}
.cat svg{width:28px;height:28px;stroke:var(--accent);fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
@media (hover:hover){.cat:hover{border-color:var(--accent);color:var(--ink);transform:translateY(-2px);box-shadow:var(--shadow-1)}}
.cat:active{transform:scale(.96)}
.stat-line{display:flex;flex-wrap:wrap;gap:6px 22px;margin:14px 0 0;padding:0;list-style:none;font-size:var(--fs-meta);color:var(--muted)}
.stat-line b{font-size:17px;color:var(--ink);font-variant-numeric:tabular-nums;margin-right:4px}

/* ───────── snap rails with prev/next (all four references) ───────── */
.rail-head{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;margin-bottom:16px}
.rail-head .sub{margin:4px 0 0}
.rail-head p{margin:4px 0 0}
.rail-nav{display:none;gap:8px;flex-shrink:0}
.js .rail-nav{display:flex}
@media (max-width:719px),(hover:none){.js .rail-nav{display:none}}
.rail-nav button{width:44px;height:44px;border-radius:50%;border:1px solid var(--field-line);background:var(--card);color:var(--ink);cursor:pointer;
  display:grid;place-items:center;transition:border-color var(--t-fast),opacity var(--t-fast),transform var(--t-fast) var(--ease)}
.rail-nav button svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.rail-nav button:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
.rail-nav button:active:not(:disabled){transform:scale(.92)}
.rail-nav button:disabled{opacity:.35;cursor:default}
.rail{display:grid;grid-auto-flow:column;grid-auto-columns:var(--col,72%);gap:var(--rail-gap);overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-padding:0 16px;margin:0 -16px;padding:4px 16px 14px;list-style:none;scrollbar-width:none}
.rail::-webkit-scrollbar{display:none}
.rail > li{scroll-snap-align:start;min-width:0}
.rail.r-tall{--col:58%}
@media (min-width:720px){
  .rail{margin:0 -32px;padding:8px 32px 24px;scroll-padding:0 32px;--col:calc((100% - 2 * var(--rail-gap)) / 2.6)}
  .rail.r-tall{--col:calc((100% - 3 * var(--rail-gap)) / 3.6)}
}
@media (min-width:1100px){
  .rail{--col:calc((100% - 3 * var(--rail-gap)) / 3.4)}
  .rail.r-tall{--col:calc((100% - 5 * var(--rail-gap)) / 5.5)}
}
@media (min-width:1244px){.rail{margin:0 -24px;padding:8px 24px 30px;scroll-padding:0 24px}}  /* bleed into the gutter so hover shadows are not clipped; cards stay aligned */

/* ───────── image tile (district / use / size / post): the whole tile is one link ───────── */
.tile{position:relative;height:100%}
.tile-link{display:flex;flex-direction:column;gap:10px;height:100%;color:var(--ink);text-decoration:none}
.tile-link:hover{color:var(--ink)}
.tile-link:focus-visible{outline:0}
.tile-link:focus-visible .ph-box{outline:3px solid var(--focus);outline-offset:2px}
.tile h3{font-size:17px;line-height:1.4}
.tile .meta{font-size:var(--fs-meta);line-height:1.5;color:var(--muted);margin:0}
.tile .price-from{font-size:15px;color:var(--ink);margin:0}
.tile .price-from b{color:var(--amber);font-weight:900;font-variant-numeric:tabular-nums}
.tile.t-portrait .ph-box{--ar:4/5}
.tile.t-overlay .ph-box::after{content:"";position:absolute;inset:auto 0 0 0;height:65%;z-index:1;
  background:linear-gradient(to top,rgba(var(--scrim),.9) 0%,rgba(var(--scrim),.72) 45%,rgba(var(--scrim),0) 100%)}
.tile.t-overlay .on-photo{position:absolute;left:14px;right:14px;bottom:12px;z-index:2;color:#fff}
.tile.t-overlay .on-photo b{display:block;font-size:20px;line-height:1.25;font-weight:700}
.tile.t-overlay .on-photo span{display:block;font-size:13.5px;line-height:1.45;color:#e6eefb}
.tile .body{display:flex;flex-direction:column;gap:4px}
.tile .more{margin-top:2px}

/* ───────── save heart (Airbnb) — JS only, stored per viewer in localStorage ───────── */
.save{position:absolute;top:10px;right:10px;z-index:3;width:44px;height:44px;border-radius:50%;border:0;cursor:pointer;
  background:var(--chip-on-photo);box-shadow:0 2px 8px rgba(var(--scrim),.18);display:grid;place-items:center;
  transition:transform var(--t-fast) var(--ease)}
html:not(.js) .save{display:none}
.save svg{width:22px;height:22px;fill:transparent;stroke:var(--ink);stroke-width:2;stroke-linejoin:round;transition:fill var(--t-fast),stroke var(--t-fast)}
.save[aria-pressed="true"] svg{fill:var(--heart);stroke:var(--heart)}
.save:active{transform:scale(.88)}
.save.pop svg{animation:heart .45s var(--spring)}
@keyframes heart{40%{transform:scale(1.3)}}

/* ───────── carousel with dots (size + use cards) ───────── */
.carousel{--ar:3/2}
.carousel .slides{position:absolute;inset:0;display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior-x:contain}
.carousel .slides::-webkit-scrollbar{display:none}
.carousel .slide{position:relative;flex:0 0 100%;scroll-snap-align:start;scroll-snap-stop:always}
.carousel .slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:var(--img-dim);transition:opacity .35s var(--ease)}
.carousel .slide.ill{background:#f3f7fb}
.carousel .slide.ill img{object-fit:contain;padding:4%}
.carousel .slide .ph-tag{bottom:auto;top:10px}
.dots{position:absolute;left:0;right:0;bottom:0;z-index:2;display:flex;justify-content:center;gap:0}
html:not(.js) .dots{display:none}
.dots button{width:44px;height:44px;border:0;background:none;padding:0;cursor:pointer;display:grid;place-items:center}
.dots button::before{content:"";width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.7);box-shadow:0 0 0 1.5px rgba(var(--scrim),.6);transition:transform var(--t-fast),background var(--t-fast)}
.dots button[aria-current="true"]::before{background:#fff;transform:scale(1.35)}
.car-btn{position:absolute;top:50%;z-index:2;width:36px;height:36px;margin-top:-18px;border-radius:50%;border:0;background:var(--chip-on-photo);color:var(--ink);cursor:pointer;
  display:none;place-items:center;opacity:0;transition:opacity var(--t-fast)}
.car-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.car-btn.prev{left:8px}.car-btn.next{right:8px}
@media (hover:hover) and (min-width:720px){.js .car-btn{display:grid}.carousel:hover .car-btn,.car-btn:focus-visible{opacity:1}}

/* ───────── image card with body (use + size pages) ───────── */
.lcard{position:relative;display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-1);overflow:hidden;
  transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t)}
.lcard > .ph-box{border-radius:0}
.lcard .body{padding:18px var(--card-pad) var(--card-pad);display:flex;flex-direction:column;gap:8px;flex:1}
.lcard h2,.lcard h3{font-size:clamp(20px,2.2vw,24px)}
.lcard .row-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
.lcard a.more::before{content:"";position:absolute;inset:0;z-index:1}
.lcard .carousel{z-index:2}
@media (hover:hover){.lcard:hover{transform:translateY(-3px);box-shadow:var(--shadow-2);border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}}
.lcard.match{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow),var(--shadow-2)}
.lcard.match::after{content:"建議";position:absolute;top:12px;right:12px;z-index:3;font-size:13px;font-weight:700;color:var(--on-accent);background:var(--accent);padding:4px 12px;border-radius:999px;animation:pop .4s var(--spring)}
.g-img2{display:grid;gap:var(--gap);grid-template-columns:1fr}
@media (min-width:720px){.g-img2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1100px){.g-img2.c3{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ───────── operator listing cards (neutral 格 visual, price-first rhythm) ───────── */
.op-tools{display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;align-items:center;margin-bottom:18px}
.view-toggle{display:none;padding:4px;border-radius:999px;background:var(--bg-2);border:1px solid var(--line)}
.js .view-toggle{display:inline-flex}
@media (max-width:859px){.js .view-toggle{display:none}}
.view-toggle button{min-height:40px;min-width:44px;padding:0 14px;border:0;border-radius:999px;background:none;color:var(--muted);font:inherit;font-size:14.5px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.view-toggle button svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2}
.view-toggle button[aria-pressed="true"]{background:var(--card);color:var(--ink);box-shadow:var(--shadow-1)}
.op-grid{display:grid;gap:var(--gap);grid-template-columns:1fr}
@media (min-width:600px){.op-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1000px){.op-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
.op{position:relative;display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-1);overflow:hidden;
  transition:transform var(--t) var(--ease),box-shadow var(--t) var(--ease),border-color var(--t)}
@media (hover:hover){.op:hover{transform:translateY(-3px);box-shadow:var(--shadow-2);border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}}
.op-visual{position:relative;aspect-ratio:16/7;background:var(--hero-bg);display:flex;align-items:flex-end;padding:14px 16px;overflow:hidden}
.op-visual::before{content:"";position:absolute;inset:0;background-image:linear-gradient(var(--hero-line) 1.5px,transparent 1.5px),linear-gradient(90deg,var(--hero-line) 1.5px,transparent 1.5px);
  background-size:28px 28px;background-position:-1px -1px;transition:transform .6s var(--ease)}
@media (hover:hover){.op:hover .op-visual::before{transform:scale(1.06)}}
.op-visual span{position:relative;font-size:clamp(20px,2.2vw,24px);font-weight:900;color:var(--hero-ink);letter-spacing:.01em;line-height:1.2}
.op-body{display:flex;flex-direction:column;gap:10px;padding:16px var(--card-pad) var(--card-pad);flex:1}
.op-name{font-size:18px;line-height:1.35}
.op-name small{display:block;font-size:13.5px;font-weight:400;color:var(--muted)}
.op-meta{display:flex;flex-wrap:wrap;gap:4px 18px;margin:0;font-size:14.5px}
.op-meta div{display:flex;gap:6px}
.op-meta dt{color:var(--muted)} .op-meta dd{margin:0;font-weight:700;font-variant-numeric:tabular-nums}
.op-price{margin-top:auto;padding-top:12px;border-top:1px solid var(--line-soft)}
.op-price .lab{display:block;font-size:13px;color:var(--muted)}
.op-price .price{display:inline-block;color:var(--amber);font-size:24px;font-weight:900;line-height:1.25;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.op-price .per{font-size:14px;color:var(--muted);margin-left:2px}
.op-price small.promo{display:block;color:var(--muted);font-size:13px;font-weight:500}
.op-price .tbc{display:inline-block;font-size:16px;padding:4px 0}
.op small.op-note{display:block;color:var(--muted);font-size:13px;line-height:1.55}
.op-link{font-weight:700;text-decoration:none;display:inline-flex;align-items:center;gap:6px;min-height:44px}
.op-link::after{content:"→";transition:transform var(--t) var(--spring)}
.op-link::before{content:"";position:absolute;inset:0;z-index:1}
.op:hover .op-link::after{transform:translateX(4px)}
.op:has(.op-link:focus-visible){outline:3px solid var(--focus);outline-offset:2px}
.op-link:focus-visible{outline:0}
/* list view: one operator per row, price column on the right (desktop) */
@media (min-width:860px){
  .op-grid.is-list{grid-template-columns:1fr;gap:10px}
  .op-grid.is-list .op{flex-direction:row;align-items:stretch}
  .op-grid.is-list .op-visual{aspect-ratio:auto;width:150px;flex-shrink:0;padding:12px 14px}
  .op-grid.is-list .op-visual span{font-size:17px}
  .op-grid.is-list .op-body{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) minmax(0,1fr) 190px;grid-template-areas:"name meta price link" "name pill price link" "note note note note";
    align-items:center;gap:6px 24px;padding:14px 64px 14px 22px}
  .op-grid.is-list .op-name{grid-area:name}
  .op-grid.is-list .op-meta{grid-area:meta}
  .op-grid.is-list .op-body > .pill{grid-area:pill;justify-self:start}
  .op-grid.is-list .op-price{grid-area:price;margin:0;padding:0;border:0}
  .op-grid.is-list .op-note{grid-area:note}
  .op-grid.is-list .op-link{grid-area:link}
  .op-grid.is-list .save{top:50%;margin-top:-22px;right:12px;background:var(--bg-2)}
}
.op-body > .pill{align-self:flex-start}
/* phones: 2-up feed (Taobao / Xiaohongshu rhythm) so a screen shows 4–6 operators, not 1–2.
   Name and price stay large; supporting text drops to caption size and long notes clamp to 3 lines
   (full note on the brand page). The whole card remains one tap target via .op-link::before. */
@media (max-width:599px){
  .op-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:start}
  .op-visual{aspect-ratio:2/1;padding:8px 12px}
  .op-visual span{font-size:15px;padding-right:44px}
  .op-name small{display:none}  /* the English name already sits in the visual above */
  .op-body{gap:6px;padding:10px 12px 6px}
  .op-name{font-size:16px}
  .op-meta{font-size:13px;gap:2px 10px}
  .op-body > .pill{font-size:12px;padding:2px 8px;gap:5px}
  .op-price{padding-top:8px}
  .op-price .lab,.op-price small.promo{font-size:12px}
  .op-price .price{font-size:20px}
  .op-price .per{font-size:12px}
  .op-price .tbc{font-size:15px;padding:2px 0}
  .op small.op-note{font-size:12px;line-height:1.5;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  .op-link{font-size:14px}
  .op .save{top:6px;right:6px}
}
/* phones: storage-type cards (use / size pages) also go 2-up */
@media (max-width:719px){
  .g-img2{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-items:start}
  .lcard .body{padding:10px 12px 8px;gap:4px}
  .lcard h2,.lcard h3{font-size:16px;line-height:1.35}
  .lcard .row-top{gap:2px 8px}
  .lcard .desc{font-size:13px;line-height:1.55;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  .lcard .note{font-size:12.5px}
  .lcard a.more{font-size:14px}
  .lcard .ph-tag{font-size:11px;padding:4px 7px;left:6px;bottom:6px}
  .lcard.match::after{top:6px;right:6px;font-size:12px;padding:3px 9px}
}
.op .save{background:var(--chip-on-photo)}
.brand-op .kv{font-size:14.5px}

/* ───────── sticky filter bar (Airbnb / Tripadvisor) ───────── */
.filterbar{position:sticky;top:64px;z-index:12;background:color-mix(in srgb,var(--bg) 92%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);margin:calc(-1 * var(--hero-gap)) 0 var(--hero-gap)}
@media (min-width:861px){.filterbar{top:62px}}
html:not(.js) .filterbar{position:static}
.filterbar .wrap{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding-top:10px;padding-bottom:10px;align-items:center}
.filterbar .wrap::-webkit-scrollbar{display:none}
.filterbar .chip{flex-shrink:0}
.filterbar .sep{flex-shrink:0;width:1px;height:28px;background:var(--line);margin:0 4px}
.filterbar a.chip{font-weight:700}

/* ───────── region groups ───────── */
.region-group{scroll-margin-top:140px}
.region-group + .region-group{margin-top:calc(var(--space-section) * .75)}
.d-grid{display:grid;gap:var(--gap) 12px;grid-template-columns:repeat(2,minmax(0,1fr));list-style:none;margin:0;padding:0}
@media (min-width:720px){.d-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gap)}}
@media (min-width:1000px){.d-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}
.d-grid .tile{scroll-margin-top:140px}
.d-grid .tile:target .ph-box{outline:3px solid var(--accent);outline-offset:3px}
@media (max-width:599px){.tile.t-overlay .on-photo b{font-size:17px}.tile.t-overlay .on-photo{left:12px;right:12px;bottom:10px}}

/* ───────── page head with a framing photo ───────── */
.page-head.has-photo .wrap{display:grid;gap:24px;align-items:center}
.page-head .head-photo{display:none}
@media (min-width:900px){
  .page-head.has-photo .wrap{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:48px}
  .page-head .head-photo{display:block;--ar:4/3;box-shadow:var(--shadow-2)}
}
.page-head.has-photo.photo-mobile .head-photo{display:block;--ar:16/9}
@media (min-width:900px){.page-head.has-photo.photo-mobile .head-photo{--ar:4/3}}

/* ───────── blog: magazine grid ───────── */
/* Blog + guide cards use the listing-card chrome (border, white body, image on top) — same family as .op/.lcard.
   Phones: 2-up feed like the operator and storage cards. */
.mag{display:grid;gap:10px;grid-template-columns:repeat(2,minmax(0,1fr));align-items:start}
.post-tile .tile-link{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-1);gap:0;
  transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.post-tile .ph-box{border-radius:0}
.post-tile .body{display:flex;flex-direction:column;gap:6px;padding:12px 12px 14px}
.post-tile .kicker{font-size:12px}
.post-tile h3{font-size:15.5px;line-height:1.45;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.post-tile .note{font-size:12.5px}
@media (min-width:720px){.post-tile .body{padding:16px var(--card-pad) var(--card-pad);gap:8px}.post-tile .kicker{font-size:13px}.post-tile h3{font-size:19px}}
@media (hover:hover){
  .post-tile:hover .tile-link{border-color:color-mix(in srgb,var(--accent) 45%,var(--line));box-shadow:var(--shadow-2)}
  .tile.post-tile:not(.t-overlay):hover .ph-box{box-shadow:none}  /* the card itself carries the ring + shadow */
}
@media (min-width:720px){.mag{gap:var(--gap)}}
@media (min-width:1000px){.mag{grid-template-columns:repeat(3,minmax(0,1fr))}.mag .post-tile.wide{grid-column:span 2}}
.post-tile .note{margin:0}
.post-tile.wide .ph-box{--ar:16/9}
.post-lead{position:relative;border-radius:var(--radius);overflow:hidden;min-height:420px;display:flex;align-items:flex-end;color:#fff;isolation:isolate}
.post-lead > .ph-box{position:absolute;inset:0;aspect-ratio:auto;border-radius:0;z-index:-1}
.post-lead > .ph-box::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(var(--scrim),.92) 0%,rgba(var(--scrim),.7) 45%,rgba(var(--scrim),.05) 85%)}
.post-lead .body{padding:28px var(--card-pad);display:flex;flex-direction:column;gap:10px;max-width:40em}
.post-lead .kicker{color:#fff;margin:0}
.post-lead h2{color:#fff}
.post-lead .desc{color:#e6eefb}
.post-lead .note{color:#d5e1f5}
.post-lead a.cover{color:#fff;text-decoration:none}
.post-lead a.cover::after{content:"";position:absolute;inset:0;z-index:1;border-radius:var(--radius)}
.post-lead a.cover:focus-visible{outline:0}
.post-lead a.cover:focus-visible::after{outline:3px solid var(--focus);outline-offset:-3px}
@media (min-width:720px){.post-lead{min-height:500px}.post-lead .body{padding:40px}}
@media (hover:hover){.post-lead:hover > .ph-box img{transform:scale(1.04)}}

/* home: small FAQ + guides layout */
.home-faq{max-width:820px}

/* numbers-first framing for price + deals */
.table-frame{position:relative}

@media (prefers-reduced-motion: reduce){
  .ph-box > img,.carousel .slide img{transition:none!important}
  .js .ph-box:has(img:not(.loaded))::before{animation:none}
  .tile:hover .ph-box > img,.lcard:hover .ph-box > img,.post-tile:hover .ph-box > img,.post-lead:hover > .ph-box img{transform:none!important}
  .op:hover .op-visual::before{transform:none}
  .tile:hover,.post-lead:hover,.js .post-lead.reveal.in:hover{transform:none}
  .rail,.carousel .slides,.cats{scroll-behavior:auto}
}
html:not(.js) .op-tools .seg{display:none} /* sort needs JS; the no-JS list is already A–Z */

/* consent banner (assets/analytics.js; only appears once a tracking ID is configured) */
.consent{position:fixed;left:16px;right:16px;bottom:16px;z-index:40;max-width:560px;margin:0 auto;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow-2);padding:16px 18px;display:flex;flex-direction:column;gap:12px}
.consent p{margin:0;font-size:14.5px;line-height:1.6}
.consent-actions{display:flex;gap:10px;justify-content:flex-end}
.btn-ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1px var(--field-line)}
.btn-ghost:hover{color:var(--ink);background:var(--bg-2);box-shadow:inset 0 0 0 1px var(--field-line)}

/* ───────── rich footer (written by tools/chrome.py) ───────── */
.site-footer{padding:48px 0 0}
/* style.css has older .site-footer .wrap{display:flex} / .site-footer nav{display:flex} rules — out-rank them here */
.site-footer .foot-grid{display:grid;gap:28px 20px;grid-template-columns:repeat(2,minmax(0,1fr));justify-content:initial}
.site-footer nav.foot-col{display:block}
.site-footer .foot-bottom{display:flex}
.foot-brand{grid-column:1 / -1;display:flex;flex-direction:column;gap:10px;max-width:34em}
.foot-brand p{margin:0;color:var(--on-dark);font-size:14.5px;line-height:1.65}
.foot-brand .foot-meta{font-size:13px;opacity:.85}
.logo-inverse,.logo-inverse:hover{color:#fff;background:none!important;min-height:0}
.logo-inverse small{color:var(--on-dark)}
.foot-col h2{font-family:var(--sans);font-size:14px;font-weight:700;letter-spacing:.04em;color:#fff;margin:0 0 6px}
.foot-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.foot-col li a{color:var(--on-dark);font-size:14.5px}
.foot-col li a:hover{color:#fff}
.foot-areas{grid-column:1 / -1}
.foot-areas ul{gap:6px}
.foot-area{display:flex;flex-wrap:wrap;align-items:center;column-gap:14px}
.foot-area span{flex:0 0 40px;font-size:13px;font-weight:700;color:#fff}
.foot-bottom{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 20px;margin-top:32px;padding-top:12px;padding-bottom:20px;
  border-top:1px solid color-mix(in srgb,var(--on-dark) 25%,transparent);font-size:13px;color:var(--on-dark)}
.foot-links{display:flex;gap:18px;align-items:center}
.linkbtn{background:none;border:0;padding:0;font:inherit;color:var(--on-dark);cursor:pointer;min-height:44px;text-decoration:underline;text-underline-offset:3px}
.linkbtn:hover{color:#fff}
.consent-link{display:none}
.has-analytics .consent-link{display:inline-flex;align-items:center}
@media (min-width:720px){
  .site-footer .foot-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  .foot-brand{grid-column:1 / 3}
  .foot-areas{grid-column:3 / 5;grid-row:1}
}
@media (min-width:1100px){
  .site-footer .foot-grid{grid-template-columns:1.6fr 1fr 1.7fr 1fr 1fr 1fr}
  .foot-brand,.foot-areas{grid-column:auto;grid-row:auto}
  .foot-col li a{min-height:34px}
}

/* ───────── 附近迷你倉 (near/) ───────── */
.near-tool{display:flex;flex-direction:column;gap:16px;max-width:760px}
.near-gps{align-self:flex-start;gap:10px;min-height:52px;padding:0 24px;font-size:17px}
.near-gps svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.near-gps.is-busy svg{animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.near-or{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:13px}
.near-or::before,.near-or::after{content:"";flex:1;height:1px;background:var(--line)}
.near-form label{display:block;font-size:14px;font-weight:500;color:var(--muted);margin-bottom:6px}
.near-row{display:flex;gap:10px}
.near-row input{flex:1;min-width:0;height:50px;font:inherit;font-size:16px;border:1px solid var(--field-line);border-radius:999px;background:var(--bg);color:var(--ink);padding:0 18px}
.near-row input:focus{outline:0;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);background:var(--card)}
.near-districts{display:flex;flex-direction:column;gap:8px}
.near-privacy{margin:0;font-size:13px}
.near-bar{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:12px 20px;margin-bottom:16px;scroll-margin-top:90px}
.near-status{margin:0;font-size:17px}
.near-status b{color:var(--accent)}
.near-filters{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end}
.near-filters label{display:flex;flex-direction:column;gap:4px;font-size:13px;color:var(--muted)}
.near-filters select{height:44px;font-size:15px}
.near-list{list-style:none;margin:0;padding:0;display:grid;gap:12px}
@media (min-width:900px){.near-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
.near-card{display:flex;gap:16px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-1);padding:16px}
.near-dist{flex:0 0 76px;display:flex;flex-direction:column;align-items:flex-start;gap:2px}
.near-dist b{font-size:20px;font-weight:900;color:var(--accent);line-height:1.2;font-variant-numeric:tabular-nums}
.near-dist span{font-size:12px;color:var(--muted)}
.near-main{min-width:0;display:flex;flex-direction:column;gap:6px}
.near-main h3{font-size:17px;line-height:1.4}
.near-main h3 small{font-weight:500;color:var(--muted);font-size:14px}
.near-addr{margin:0;font-size:14px;color:var(--muted);line-height:1.55}
.near-tags{margin:0;display:flex;flex-wrap:wrap;gap:6px 10px;align-items:center;font-size:13px}
.near-tag{padding:2px 10px;border-radius:999px;background:var(--bg-2);box-shadow:inset 0 0 0 1px var(--line)}
.near-tag.on{background:var(--accent-soft);color:var(--accent-ink);box-shadow:none;font-weight:700}
.near-price b{color:var(--amber);font-weight:900}
.near-actions{margin:4px 0 0;display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center}
.btn-sm{height:44px;padding:0 16px;font-size:14.5px}
.near-none{padding:24px;text-align:center;color:var(--muted);background:var(--card);border-radius:var(--radius);border:1px dashed var(--line)}
.near-more{margin:16px auto 0;display:flex}
.near-source{margin-top:16px;font-size:12.5px}
@media (max-width:599px){
  .near-card{flex-direction:column;gap:8px;padding:14px}
  .near-dist{flex:0 0 auto;flex-direction:row;align-items:baseline;gap:8px}
  .near-gps{align-self:stretch;justify-content:center}
}
@media (prefers-reduced-motion: reduce){.near-gps.is-busy svg{animation:none}}

/* ───────── FAQ page ───────── */
.faq-toc{margin-top:18px}
.faq-wrap{display:flex;flex-direction:column;gap:32px;max-width:860px}
.faq-sec{scroll-margin-top:90px}
.faq-sec h2{font-size:clamp(20px,2.4vw,24px);margin-bottom:12px}
.faq-sec .card{padding-top:6px;padding-bottom:6px}
.faq-sec details p a,.home-faq details p a{font-weight:700}

.finder-near{flex-basis:100%;display:inline-flex;align-items:center;gap:8px;min-height:44px;font-weight:700;text-decoration:none;font-size:15px}
.finder-near svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.mini-search .finder-near{display:none}

/* ───────── brand detail pages (brand/<id>/, tools/brand_pages.py) ───────── */
.bd-title{display:grid;grid-template-columns:1fr;gap:16px;align-items:center}
@media (min-width:720px){.bd-title{grid-template-columns:240px minmax(0,1fr);gap:28px}}
.bd-visual{aspect-ratio:16/10;border-radius:var(--radius);max-width:240px}
.bd-visual span{font-size:22px}
.bd-hero .lede{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.bd-cta{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 0}
.bd-note{margin:14px 0 0;font-size:14px;color:var(--hero-muted);max-width:52em}
.bd-layout{display:flex;flex-direction:column;gap:36px;padding-bottom:56px}
.bd-toc{position:sticky;top:64px;z-index:5;padding:10px 0;background:color-mix(in srgb,var(--bg) 94%,transparent);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.bd-toc::-webkit-scrollbar{display:none}
.bd-toc .chip{flex-shrink:0}
.bd-sec{scroll-margin-top:140px;display:flex;flex-direction:column;gap:14px}
.bd-head h2{font-size:clamp(21px,2.6vw,26px)}
.bd-head .note{margin:4px 0 0}
.bd-h3{font-size:17px;margin:6px 0 0}
.bd-lede{margin:0;font-size:16px;line-height:1.75;max-width:48em}
.bd-empty{margin:0;padding:18px;border:1px dashed var(--line);border-radius:var(--radius-sm);color:var(--muted);background:var(--card)}
.bd-facts{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px 18px;margin:0;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px var(--card-pad)}
.bd-facts dt{color:var(--muted);font-size:14.5px;white-space:nowrap}
.bd-facts dd{margin:0;font-weight:500}
.bd-fees{display:grid;gap:10px;margin:0}
.bd-fees dt{font-weight:700}
.bd-fees dd{margin:-6px 0 6px;color:var(--muted);font-size:15px}
a.src{font-size:13px;font-weight:500;white-space:nowrap}
.bd-list{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.bd-list > li{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:14px 16px;display:flex;flex-direction:column;gap:4px}
.bd-list p{margin:0}
.bd-district{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 16px;margin-bottom:8px}
.bd-district > summary{min-height:52px}
.bd-district > summary .note{margin-left:auto;margin-right:10px}
.bd-branches{list-style:none;margin:0 0 12px;padding:0;display:grid;gap:8px}
.bd-branches li{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 0;border-top:1px solid var(--line-soft)}
.bd-branches p{margin:2px 0 0}
.bd-map{flex-shrink:0;min-height:44px;min-width:56px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;
  box-shadow:inset 0 0 0 1px var(--field-line);font-weight:700;text-decoration:none;font-size:14px}
.bd-themes{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.bd-theme{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:14px 16px}
.bd-theme > b{display:block;margin:6px 0 6px;font-size:16px}
.bd-theme ul{margin:0;padding-left:18px;display:grid;gap:6px;font-size:14.5px}
.bd-tone{display:inline-block;font-size:12px;font-weight:700;padding:2px 10px;border-radius:999px;background:var(--bg-2);box-shadow:inset 0 0 0 1px var(--line)}
.bd-services{margin-top:4px}
.bd-services .chip{cursor:default}
.bd-sources{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 16px}
.bd-sources ul{margin:0 0 12px;padding-left:18px;display:grid;gap:4px;font-size:14px}
.bd-disclose{border-top:1px solid var(--line);padding-top:16px}
@media (max-width:599px){
  .bd-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bd-facts{grid-template-columns:1fr;gap:2px}
  .bd-facts dd{margin-bottom:8px}
}
.bd-visual{background:var(--card);box-shadow:var(--shadow-1)}
/* phones: the brand price table stays a real 3-column table (size · regular · promo) — stacked cards would mean 20+ screens */
@media (max-width:720px){
  .table.bd-prices{display:table;width:100%}
  .table.bd-prices thead{display:table-header-group}
  .table.bd-prices tbody{display:table-row-group}
  .table.bd-prices tr{display:table-row;padding:0}
  .table.bd-prices th,.table.bd-prices td{display:table-cell;width:auto;padding:10px 12px;font-size:15px}
  .table.bd-prices td[data-label]::before{content:none}
  .table.bd-prices th:nth-child(4),.table.bd-prices td:nth-child(4){display:none}
  .table.bd-prices .price{font-size:17px}
}
.post-tile .kicker{margin:0}
@media (max-width:999px){.post-tile.wide .ph-box{--ar:3/2}}  /* the 16:9 "wide" crop only makes sense in its 2-column desktop slot */
/* research text carries long URLs and English company names: let them wrap instead of widening the page */
.bd-sec,.bd-facts dd,.bd-list,.bd-theme,.bd-sources,.bd-fees dd,.bd-lede{overflow-wrap:anywhere;min-width:0}
.bd-past{margin-top:6px}
.bd-past > p{margin:0 0 10px}
.bd-past .bd-list > li{background:var(--bg);box-shadow:none}
.bd-claims{margin:0}
.prose p{margin:0;font-size:16px;line-height:1.8}

/* Custom select chevron: the native arrow hugs the right edge of the Sky pill fields.
   Drawn as an inline SVG, inset 18px from the edge, with room reserved so text never runs under it. */
select{-webkit-appearance:none;appearance:none;padding-right:46px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a586e' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 18px center;background-size:16px 16px}
select::-ms-expand{display:none}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3afc3' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")}
}
:root[data-theme="dark"] select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3afc3' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")}
select:focus{background-color:var(--card)}

/* ───────── logo as an image (concept A, assets/brand/) ───────── */
.logo picture,.logo img{display:block}
.site-header .logo img{height:40px;width:auto}
@media (min-width:861px){.site-header .logo img{height:44px}}
.foot-brand .logo img{height:46px;width:auto}
.foot-tagline{font-size:13.5px!important;color:var(--on-dark);margin:-4px 0 0!important}
