/* ==========================================================================
   Special Tools — component layer
   Include on every page, after theme.css. Nothing here hard-codes a value
   that theme.css already carries.
   ========================================================================== */

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-family);
  -webkit-text-size-adjust: 100%;
}

a { color: var(--color-brand-primary); }
a:hover { color: var(--color-brand-primary-hover); }

*:focus-visible {
  outline: 2px solid var(--color-brand-primary);
  outline-offset: 2px;
}

/* Universal tap feedback for every button app-wide, not just the new
   index-page components - a little "give" on press so buttons everywhere
   feel native rather than like a plain web page. :active (not :hover,
   which sticks after a tap on touch devices) already clears itself on
   release with no JS needed, unlike the [data-pressed] pattern list rows
   use elsewhere. Disabled buttons (the .btn-saving state) don't receive
   :active at all, so this never fights with that. */
button:not(:disabled):active {
  opacity: 0.8;
}

/* --- Banner ------------------------------------------------------------- */
/* Sits at the very top of every page. No fake status bar: the top padding
   is the device safe area, so in an installed shell the real status bar
   paints over the banner color. */
.banner {
  background: var(--color-header-bg);
  border-bottom: 1px solid var(--color-header-edge);
  /* Padding tightened from the reference's 16px/18px so a taller logo
     (below) fits without growing the banner's overall height - the two
     trade off directly: more content height needs less padding to hold
     the same total. */
  padding: calc(env(safe-area-inset-top, 0px) + 9px)
           var(--space-gutter) 10px;
  display: flex;
  align-items: center;
  gap: var(--space-md);
}
/* max-height (not a fixed height) so every shop's logo renders at a good
   size automatically regardless of its natural aspect ratio - no manual
   per-shop size control needed. max-width keeps an unusually wide logo
   from dominating the banner next to the hamburger button. 59px = 44px
   (the prior ceiling, matching the hamburger button) scaled up 1/3 -
   the banner's padding above was tightened to make room for exactly
   this, so the banner's own height still doesn't change. */
.banner-logo { max-height: 59px; max-width: 240px; width: auto; height: auto; display: block; }
/* Only applied (index.html toggles the class) when the shop's logoPlate
   setting is white|dark - never unconditionally, since the padding below
   is hard-coded rather than a CSS var, matching the reference's own
   markup where a plate is a genuinely separate path, not a default
   wrapper every logo sits in. */
.banner-plate {
  background: var(--logo-plate-bg);
  padding: 10px 12px;
  border-radius: var(--radius-card);
}
.banner-plate .banner-logo { max-height: 34px; }
.banner-wordmark-kicker {
  font: var(--text-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-brand-primary);
  margin-bottom: var(--space-xs);
}
.banner-wordmark {
  font: var(--text-banner);
  letter-spacing: -0.02em;
  color: var(--color-header-ink);
}
.banner-menu {                /* touch target stays --touch-min (44px, an
                                  accessibility floor) even though the
                                  lines drawn inside it (below) are bigger -
                                  same 1/3 scale-up as the logo, so they
                                  read as a matched pair */
  width: var(--touch-min);
  height: var(--touch-min);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 7px;
  background: none;
  border: 0;
  cursor: pointer;
}
.banner-menu i {
  display: block;
  width: 29px;
  height: 3px;
  border-radius: 3px;
  background: var(--color-header-ink);
}

/* --- Search ------------------------------------------------------------- */
.searchbar { padding: var(--space-md) var(--space-gutter) 0; position: relative; display: flex; align-items: center; }
.search-input {
  width: 100%;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 44px 0 var(--space-gutter);
  font: var(--text-search);
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-card);
}
.search-input::placeholder { color: var(--color-text-tertiary); }

/* Compact inline search field for filtering a list already on the page
   (e.g. Recent Activity) - lighter than .search-input, which assumes the
   .searchbar wrapper and a clear button. */
.list-search-input {
  width: 100%; height: var(--control-h); box-sizing: border-box; padding: 0 var(--space-gutter);
  font: 800 16px var(--font-family); background: var(--color-surface); color: var(--color-text-primary);
  border: 1px solid rgba(32,30,29,.18); border-radius: var(--radius-input); box-shadow: var(--shadow-card);
  margin-bottom: var(--space-xs);
}
.list-search-input::placeholder { color: var(--color-text-tertiary); }
.search-clear {               /* only present when the field has text */
  position: absolute;
  right: var(--space-gutter);
  width: var(--touch-min);
  height: var(--control-h);
  display: flex;
  align-items: center;
  justify-content: center;
  font: 400 18px/1 var(--font-family);
  color: var(--color-text-secondary);
  background: none;
  border: 0;
  cursor: pointer;
}

/* --- Sync line ---------------------------------------------------------- */
.sync-line {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-lg) 0;
  font: var(--text-micro);
  color: var(--color-text-secondary);
  min-height: 11px;
}
.sync-dot { width: 6px; height: 6px; border-radius: 6px; background: var(--color-success); }
.sync-line[data-state="offline"] .sync-dot { background: var(--color-warning); }

/* --- Section label ------------------------------------------------------ */
/* Hidden entirely (not just emptied) when a section has no content — an
   empty shop must never show "Recently viewed". */
.section-label {
  padding: 11px var(--space-lg) var(--space-xs);
  font: var(--text-label);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

/* --- List row ----------------------------------------------------------- */
.item-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  padding: 0 var(--space-gutter);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}
.item-list::-webkit-scrollbar { display: none; }

.item-row {
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: var(--row-min);
  padding: var(--space-sm);
  background: var(--color-surface);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  user-select: none;
  transition: var(--press-transition);
}
/* Touch feedback: fills on finger-down, clears on release. Use pointer
   events, not :hover — :hover sticks after a tap on touch devices. */
.item-row[data-pressed="true"] { background: var(--color-surface-alt); }

.item-thumb {
  width: 52px;
  height: 52px;
  flex: none;
  overflow: hidden;
  background: var(--color-surface-alt);
  border-radius: var(--radius-thumb);
  background-size: cover;
  background-position: center;
}
/* Photos are set as background-image, not <img src>, so a row can never
   flash a broken-image icon while data is loading. */

.thumb-empty {                /* item with no photo */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  color: var(--color-text-tertiary);
  padding: 0 4px;
  box-sizing: border-box;
  overflow: hidden;
}
.thumb-empty .glyph { font: 400 17px/1 var(--font-family); }
.thumb-empty .id {
  font: 800 8px/1 ui-monospace, Menlo, monospace;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-row .body { flex: 1; min-width: 0; }
.item-row .title { font: var(--text-row-title); }
.item-row .meta { font: var(--text-meta); color: var(--color-text-secondary); }
.item-row .status { font: var(--text-status); text-align: right; max-width: 86px; }
.status--due { color: var(--color-danger); }
.status--out { color: var(--color-warning); }
.status--ok  { color: var(--color-text-secondary); }

/* --- Result card (the swipe carousel) ----------------------------------- */
.card-track {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: var(--space-sm);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding: 0 var(--space-gutter);
}
.card-track::-webkit-scrollbar { display: none; }

.item-card {
  flex: 0 0 100%;
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  background: var(--color-surface);
  border-radius: 14px;
  box-shadow: var(--shadow-raised);
  cursor: pointer;
}
.item-card .photo {
  flex: 1;
  min-height: 0;
  position: relative;
  background: var(--color-surface-alt);
  background-size: cover;
  background-position: center;
}
.item-card .id-chip {
  position: absolute;
  top: var(--space-sm);
  left: var(--space-sm);
  padding: 3px var(--space-sm);
  border-radius: var(--radius-pill);
  font: var(--text-mono-id);
  background: rgba(32, 30, 29, 0.85);
  color: var(--color-bg);
}
.item-card .info { padding: 10px 13px 13px; }
.item-card .title { font: var(--text-card-title); }
.item-card .meta { font: 400 12px/1.5 var(--font-family); color: var(--color-text-secondary); }

.photo-empty {                /* card-size no-photo treatment */
  width: 100%; height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 7px;
}
.photo-empty .glyph { font: 400 44px/1 var(--font-family); color: rgba(32,30,29,0.3); }
.photo-empty .label {
  font: var(--text-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.photo-empty .add {
  min-height: 40px;
  display: flex; align-items: center;
  padding: 0 var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-card);
  font: 800 11.5px var(--font-family);
  color: var(--color-text-primary);
}

.dots { display: flex; justify-content: center; gap: 5px; padding: var(--space-sm) 0 0; }
.dots i { width: 14px; height: 3px; border-radius: 2px; background: rgba(32,30,29,0.25); display: block; }
.dots i[data-active="true"] { background: var(--color-brand-primary); }

/* --- Footer: divider, alert strip, primary action ----------------------- */
.footer-rule {
  border-top: 1px dashed rgba(32, 30, 29, 0.3);
  margin: var(--space-md) var(--space-lg) 0;
}
.alert-strip {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: var(--space-md) var(--space-gutter) 0;
  min-height: var(--control-h);
  padding: var(--space-md);
  background: var(--color-surface);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
.alert-strip .bar { width: 4px; align-self: stretch; border-radius: 4px; background: var(--color-brand-primary); }
.alert-strip .text { flex: 1; font: 400 12.5px/1.4 var(--font-family); }
.alert-strip .text strong { font-weight: 800; }
.alert-strip .more { font: 800 12px var(--font-family); color: var(--color-brand-primary); white-space: nowrap; }

.btn-primary {
  margin: var(--space-md) var(--space-gutter) 10px;
  height: var(--control-h);
  padding: 0 var(--space-lg);
  font: 800 14.5px var(--font-family);
  color: #ffffff;
  background: var(--color-brand-primary);
  border: 0;
  border-radius: var(--radius-button);
  cursor: pointer;
  text-align: left;          /* labels are flush left, never centered */
}
.btn-primary:active { background: var(--color-brand-primary-hover); }

/* Home-bar gap for installed shells */
.home-gap { height: calc(env(safe-area-inset-bottom, 8px) + 8px); }

/* --- Empty / no-result states ------------------------------------------ */
.state-pane {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 11px;
  padding: 0 32px;
  text-align: center;
}
.state-pane .headline { font: 800 18px/1.25 var(--font-family); }
.state-pane .copy { font: var(--text-body); color: var(--color-text-secondary); }
.state-pane .actions { display: flex; gap: var(--space-sm); margin-top: 4px; }
.state-pane .btn,
.state-pane .btn-outline {
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  padding: 0 var(--space-lg);
  border-radius: var(--radius-button);
  font: 800 12.5px var(--font-family);
  cursor: pointer;
}
.state-pane .btn { background: var(--color-brand-primary); color: var(--color-on-brand-primary); border: 0; }
.state-pane .btn-outline { background: var(--color-surface); color: var(--color-text-primary); border: 1px solid var(--color-border); }
.state-pane .add-glyph {
  width: 56px; height: 56px;
  border: 2px dashed rgba(32, 30, 29, 0.3);
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font: 400 26px/1 var(--font-family);
  color: rgba(32, 30, 29, 0.35);
}

/* Offline: show the cached list, dimmed, with photos suppressed so nothing
   looks broken. Rows are not pressable while offline. */
.item-list[data-offline="true"] { opacity: 0.5; pointer-events: none; }

/* --- Powered-by footer, every page ---------------------------------------
   Same dashed divider as .footer-rule, same text size as .sync-line's
   "Updated just now" (--text-micro). flex:none by design - on pages using
   the shared page shell / index.html's flex column, this just eats a
   little of #content's or .page-body's flex:1 space rather than growing
   the page past one screen. */
.powered-by-rule {
  flex: none;
  border-top: 1px dashed rgba(32, 30, 29, 0.3);
  margin: var(--space-sm) var(--space-lg) 0;
}
.powered-by {
  flex: none;
  text-align: center;
  padding: var(--space-xs) var(--space-lg);
  font: var(--text-micro);
  color: var(--color-text-secondary);
}
.powered-by b { font-weight: 800; color: var(--color-text-primary); }
.item-list[data-offline="true"] .item-thumb { background-image: none !important; }
