/* public/css/rails.css -- the look of the three rails, shared by every page.
 *
 * Lifted verbatim out of tools/make-coldwater.mjs (cw-logorow-style) alongside
 * public/js/rails.js; see that file's header for why. NicotiaMarket's class
 * names are kept deliberately -- .logorow/.lrhead/.lrwrap/.lrscroll/.lchip/
 * .limg -- so the two sites' strips stay recognisably one component.
 */
/* SHOP BY STORE, ported from NicotiaMarket's logo strip.
   Copied rather than reinvented so the two sister sites read as one family:
   same class names (.logorow/.lrhead/.lrwrap/.lrscroll/.lchip/.limg), same
   circular white plate, same monogram fallback, same edge-fade-plus-arrows
   affordance, same gold selected state. --gold is a shared family token, which
   is why the selected chip stays gold on a cold-blue page instead of drifting
   to the local accent.

   The white plate is load bearing rather than decorative: a shop's mark is
   drawn for light backgrounds and vanishes on ours. */
.logorow{padding:14px 0 4px}
/* TWO FACETS SIDE BY SIDE, WITH THE PAGE'S MIDDLE DRAWN BETWEEN THEM.
   Which shop and what kind of thing are the two questions a walk-in shopper
   actually asks, and stacking them as two full-width rails pushed the second one
   under the fold on a laptop -- so the one a shopper wanted was the one they had
   to scroll for.
   The divider is its own 1px GRID TRACK rather than a border on either rail, so
   it lands on the shell's exact midpoint and cannot drift when one side's chips
   are wider than the other's. min-width:0 on the columns is load bearing: a grid
   child sizes to min-content by default, and a rail of 104px chips would widen
   its own track instead of scrolling inside it -- which is the horizontal
   overflow test-coldwater-page.mjs asserts against at 390px. */
.lrpair{display:grid;grid-template-columns:1fr 1px 1fr;gap:0 22px;align-items:start}
.lrpair>.lrpair-col{min-width:0}
/* BRIGHTER THAN THIS PAGE'S OTHER HAIRLINES, on purpose. At --glass-line's own
   0.22 alpha the rule was there and nobody could see it, which makes it furniture
   rather than a divider: the whole job is to say "these are two different
   questions". The accent at 0.42 with a soft bloom reads as drawn at a glance and
   still is not louder than the chips it separates. */
.lrsplit{align-self:stretch;width:1px;margin:16px 0 8px;position:relative;
  background:linear-gradient(180deg,transparent,
    rgba(var(--accent-rgb,120,180,215),.42) 10%,
    rgba(var(--accent-rgb,120,180,215),.42) 90%,transparent);
  box-shadow:0 0 9px rgba(var(--accent-rgb,120,180,215),.20)}
/* A dot on the midpoint, so the line reads as drawn on purpose rather than as a
   seam between two panels that failed to meet. */
.lrsplit::after{content:"";position:absolute;left:50%;top:50%;width:6px;height:6px;
  margin:-3px 0 0 -3px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 0 4px var(--bg),0 0 10px rgba(240,185,60,.45)}
@media(max-width:900px){
  /* One column, and the divider TURNS WITH IT rather than being deleted: without
     a rule between them the two rails read as one long row of unrelated circles,
     which is exactly the confusion the divider exists to prevent. */
  .lrpair{grid-template-columns:1fr;gap:0}
  .lrsplit{width:auto;height:1px;margin:12px 0 4px;
    background:linear-gradient(90deg,transparent,
      rgba(var(--accent-rgb,120,180,215),.42) 10%,
      rgba(var(--accent-rgb,120,180,215),.42) 90%,transparent)}
}
.lrhead{display:flex;align-items:baseline;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.lrhead h2{font-weight:900;font-size:13.5px;letter-spacing:.06em;text-transform:uppercase;margin:0}
.lrhead small{font-size:11.5px;color:var(--dim)}
.lrclear{margin-left:auto;background:none;border:none;color:var(--gold);cursor:pointer;
  font-size:11.5px;letter-spacing:.04em;text-decoration:underline;padding:0}
.lrwrap{position:relative}
/* TRULY SCROLLABLE, not a slideshow with two buttons. Three things were
   stopping it and all three are CSS:
     - scroll-behavior:smooth applies to the USER's wheel and drag as well as to
       the arrows, so every flick was animated and the rail felt like it was
       paging rather than following the hand. The arrows pass behavior:"smooth"
       in their own scrollBy call, so they keep the animation and nothing else
       gets it.
     - scroll-snap-type fought a free drag: let go between chips and the rail
       pulled back to a chip, which reads as the rail refusing to be scrolled.
     - the scrollbar was hidden outright, so nothing on screen said the rail
       scrolls at all. It is a slim tinted one now rather than none: on a
       trackpad or a touchscreen it is the only affordance there is. */
.lrscroll{display:flex;gap:10px;overflow-x:auto;padding:2px 0 6px;
  scroll-snap-type:none;
  /* Momentum on iOS, and CONTAIN so a horizontal flick cannot chain into the
     page or trigger the browser's back-swipe -- which is the single most
     annoying thing a carousel does on a phone. */
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  /* Snap targets stop clear of the fade rather than under it. */
  scroll-padding-left:2px;scroll-padding-right:46px;
  cursor:grab}
.lrscroll.dragging{cursor:grabbing;scroll-behavior:auto;scroll-snap-type:none}
.lrscroll.dragging *{pointer-events:none}
/* NO SCROLLBAR. A visible one was the first attempt at saying "this scrolls"
   and it is the wrong answer: a 6px grey rule under a row of circular photo
   plates is the only square-edged thing on the page, it sits there permanently
   whether or not anyone is looking at the rail, and on a Mac it is invisible
   until you touch the trackpad anyway -- so it is ugly on the platforms that
   show it and absent on the ones that do not.
   The FADE is the affordance instead, and it is a better one: content visibly
   running under a soft edge says "there is more that way" without drawing a
   control, and it disappears by itself at each end because the class driving it
   is computed from the real scroll position. */
.lrscroll{scrollbar-width:none;-ms-overflow-style:none}
.lrscroll::-webkit-scrollbar{display:none;width:0;height:0}
/* No snap alignment either: this pairs with scroll-snap-type:none above, and
   leaving the per-child rule behind is how a rail that "should" scroll freely
   still tugs on some engines. */
/* Fades read as "more this way" rather than as a clipped image, and are the
   affordance now the scrollbar is gone. Pointer-events off or they eat clicks
   on the end chips. */
.lrwrap::before,.lrwrap::after{content:"";position:absolute;top:0;bottom:6px;width:46px;
  pointer-events:none;opacity:0;transition:opacity .2s;z-index:1}
.lrwrap::before{left:0;background:linear-gradient(90deg,var(--bg),transparent)}
.lrwrap::after{right:0;background:linear-gradient(270deg,var(--bg),transparent)}
.lrwrap.can-prev::before{opacity:1}
.lrwrap.can-next::after{opacity:1}
/* NO ARROWS. They were the third attempt at saying "this scrolls" and they are
   the wrong answer for the same reason the scrollbar was: a pair of nudge
   buttons is a control the rail does not need, it only moves the rail one step
   at a time, and its presence makes people press it instead of discovering that
   the thing scrolls under the hand. A rail should follow a two-finger trackpad
   gesture, a swipe and a mouse drag -- all three are wired in cw-carousel -- and
   say "there is more that way" with the fade. That is what nicotinemarket.com
   does, which is what this strip was ported from. */
.lrctl{margin-left:auto;display:flex;align-items:center;gap:7px}
.lrctl .lrclear{margin-left:0}
@media(prefers-reduced-motion:reduce){.lrscroll{scroll-behavior:auto}}
.lchip{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:8px;
  width:104px;padding:13px 8px 11px;border:1px solid var(--line);background:var(--panel);
  border-radius:14px;cursor:pointer;transition:all .16s;position:relative}
.lchip{transition:transform .18s cubic-bezier(.2,.7,.3,1),border-color .16s,background .16s}
.lchip:hover{border-color:var(--glass-line);transform:translateY(-2px)}
.lchip .limg{transition:transform .22s cubic-bezier(.2,.7,.3,1)}
.lchip:hover .limg{transform:scale(1.06)}
.lchip:active{transform:translateY(-1px) scale(.985)}
@media(prefers-reduced-motion:reduce){
  .lchip,.lchip .limg{transition:none}
  .lchip:hover{transform:none}
  .lchip:hover .limg{transform:none}
}
.lchip.on{border-color:var(--gold);background:rgba(240,185,60,.07)}
.lchip.on::after{content:"\2713";position:absolute;top:6px;right:8px;color:var(--gold);
  font-size:11px;font-weight:700}
.limg{width:54px;height:54px;border-radius:50%;background:#fff;overflow:hidden;
  display:flex;align-items:center;justify-content:center;flex:none;
  box-shadow:0 2px 10px rgba(0,0,0,.28)}
.limg img{width:100%;height:100%;object-fit:contain;padding:7px}
/* A real letter on a real plate, tinted per store, so a logo-less row still
   reads as distinct shops rather than as a column of blanks. */
.limg.mono{background:linear-gradient(150deg,var(--mono-a,#2b3630),var(--mono-b,#1a221d))}
/* A BRAND HAS NO FAVICON, because it has no domain in this feed. Its own
   product photo is the picture, laid over the monogram plate so a failed
   load uncovers the initials instead of leaving a hole. object-fit:cover
   rather than contain: a product shot is a photo, not a logo on white. */
/* The drawn category mark: contained and padded like a logo, never cropped
   like a photograph -- .bimg above is object-fit:cover on purpose and would
   cut the edges off a 64-viewBox drawing. */
.limg .cimg{width:100%;height:100%;object-fit:contain;padding:11px;border-radius:0}
.limg.cat{background:linear-gradient(150deg,var(--mono-a,#2b3630),var(--mono-b,#1a221d))}
.limg.cat::after{content:none}
@media(max-width:560px){.limg .cimg{padding:9px}}
.limg .bimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;padding:0;border-radius:50%}
/* The favicon sits OVER the monogram and is invisible until it has decoded, so
   a slow third-party lookup never shows as a blank white disc. It carries its
   own white backing because a shop's mark is drawn for light grounds. */
.limg .fimg{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:7px;
  background:#fff;border-radius:50%;opacity:0;transition:opacity .18s ease}
.limg .fimg.ok{opacity:1}
@media(prefers-reduced-motion:reduce){.limg .fimg{transition:none}}
.limg{position:relative}
.limg.mono::after{content:attr(data-letter);font-weight:900;font-size:22px;color:#fff;letter-spacing:.02em}
.lname{font-weight:600;font-size:11.5px;line-height:1.25;text-align:center;color:var(--muted);
  max-width:100%;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.lchip.on .lname{color:var(--text)}
.lcount{font-size:10px;letter-spacing:.04em;color:var(--dim)}
.lchip.on .lcount{color:var(--gold)}
@media(max-width:560px){
  .lchip{width:86px;padding:11px 6px 9px}
  .limg{width:46px;height:46px}
  .limg.mono::after{font-size:19px}
}
