/* ==================================================================
 * palapa-365.css — "365" (Microsoft Fluent 2 / M365) re-skin for the
 * strichliste kiosk.
 *
 * Pure CSS, injected via docker/config/default.conf. Re-skins the whole site by
 * REMAPPING strichliste's own theme CSS variables to the Fluent 2 palette (every
 * view reads those variables), plus Fluent specifics: tight 4px corners,
 * Semibold buttons, restrained layered elevation on cards, a SOFT brand-tinted
 * gradient on the front-page user cards, and the gradient "+" brand mark.
 *
 * Fluent 2 principles followed (per the M365 design brief):
 *  - Surfaces are essentially FLAT; depth = restrained ambient+directional
 *    shadow (blur-heavy, ~0 offset, low opacity). The card gradient is kept
 *    deliberately SOFT so it reads as a brand tint, not a statement.
 *  - Brand blue is Fluent's #0F6CBD (light) / #479EF5 (dark, brightened for
 *    contrast) — NOT the older #0078D4 communication blue.
 *  - The expressive gradient lives on the WORDMARK ("+") only.
 *  - TOUCH-ONLY kiosk: NO :hover states; tap feedback uses :active instead.
 *  - Font is intentionally NOT changed (kiosk keeps strichliste's typeface).
 *
 * Kept in ONE file so the design can be iterated / reverted on its own.
 * Light = `html {…}`, dark = `html[data-theme='dark'] {…}`.
 * ================================================================== */

/* ---- Palette remap: LIGHT (Fluent 2 neutrals + Microsoft brand blue) ---- */
html {
  --mainBackground: #ebeae8;          /* Fluent canvas (grayer, so cards pop) */
  --headerBackground: #ffffff;        /* white app bar                 */
  --componentBackgroundDark: #ffffff; /* paper / cards / surfaces      */
  --componentBackgroundLight: #ffffff;
  --border: #e1dfdd;                  /* Fluent neutral stroke         */
  --primary: #0f6cbd;                 /* Fluent 2 brand blue           */
  --text: #242424;                    /* Fluent neutral foreground     */
  --textSubtile: #616161;             /* Fluent neutral foreground 2   */
  --buttonHighlightBackground: #0f6cbd;
  --buttonHighlightFont: #ffffff;
}

/* ---- Palette remap: DARK (Fluent dark neutrals + brand-on-dark blue) ---- */
html[data-theme='dark'] {
  --mainBackground: #080808;          /* Fluent dark canvas (deeper, cards pop) */
  --headerBackground: #1f1f1f;        /* Fluent elevation surface      */
  --componentBackgroundDark: #1f1f1f; /* cards / surfaces              */
  --componentBackgroundLight: #2b2b2b;
  --border: #303030;                  /* Fluent dark stroke            */
  --primary: #479ef5;                 /* Fluent brand-on-dark          */
  --text: #ffffff;
  --textSubtile: #adadad;
  --buttonHighlightBackground: #479ef5;
  --buttonHighlightFont: #ffffff;
}

/* ---- Fluent Semibold on buttons (Fluent leans on Semibold for prominence). */
[class*="button_"] {
  font-weight: 600;
}

/* ==================================================================
 * Front-page user cards.
 *
 * Flat Fluent surface with a SOFT brand-tinted gradient (subtle — a wash, not
 * a fill, so the name/balance read fine straight across it) + the restrained
 * Fluent shadow8 elevation. NO hover (touch-only); :active gives a gentle
 * "pressed-in" cue on tap.
 * ================================================================== */
[class*="user-card_userCard"] {
  border: 1px solid var(--border) !important;
  border-radius: 4px !important; /* half of 8 — tighter look */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); /* subtler drop shadow */
  /* off-WHITE surface (near-white, soft blue lower wash) on the grey canvas */
  background:
    linear-gradient(160deg, #fcfcfb 0%, #f4f8fd 58%, #edf3fb 100%) !important;
}
[class*="user-card_userCard"]:active {
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.1);
}
html[data-theme='dark'] [class*="user-card_userCard"] {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); /* subtler */
  /* dark greyish-blue surface — darker + less saturated than navy */
  background:
    linear-gradient(160deg, #14181e 0%, #171d26 58%, #1a2330 100%) !important;
}
html[data-theme='dark'] [class*="user-card_userCard"]:active {
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.3);
}

/* ==================================================================
 * "+" brand mark — the one Fluent-sanctioned home for the iconic gradient.
 * Appended after the "Strichliste" wordmark in the top-left nav (which already
 * sits next to the tally icon). Blue→indigo gradient text, brightened in dark.
 * ================================================================== */
[class*="header-nav_nav"] a[href="#!/user"]::after {
  content: "+";
  margin-left: 0.12em;
  font-weight: 700;
  font-size: 1.25em;
  line-height: 1;
  background: linear-gradient(135deg, #0f6cbd 0%, #3b6fe0 50%, #6e4ff0 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
html[data-theme='dark'] [class*="header-nav_nav"] a[href="#!/user"]::after {
  background: linear-gradient(135deg, #479ef5 0%, #6e8bf5 50%, #9b7bf5 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ==================================================================
 * Touch affordances — TOUCH-ONLY kiosk, so there is no hover to reveal that
 * something is clickable. Every interactive control gets a RESTING subtle fill
 * (Fluent "subtle button" feel) so it reads as tappable, plus an :active press
 * state. We also neutralise strichliste's hover-only reveals (which are dead on
 * touch / go sticky after a tap).
 * ================================================================== */

/* Top-nav links (Article List · Metrics · Search) + user-view action tabs
 * (Buy article · Edit user · Metrics). The brand link is excluded — it's the
 * logo, not a button. */
[class*="header-nav_nav"] a:not([href="#!/user"]),
[class*="button_tab"] {
  border-radius: 3px;
  padding: 0.45rem 0.6rem; /* taller tap target (fills the row, same width) */
  background: rgba(0, 0, 0, 0.05);
}
[class*="header-nav_nav"] a:not([href="#!/user"]):active,
[class*="button_tab"]:active {
  background: rgba(0, 0, 0, 0.1);
}
html[data-theme='dark'] [class*="header-nav_nav"] a:not([href="#!/user"]),
html[data-theme='dark'] [class*="button_tab"] {
  background: rgba(255, 255, 255, 0.07);
}
html[data-theme='dark'] [class*="header-nav_nav"] a:not([href="#!/user"]):active,
html[data-theme='dark'] [class*="button_tab"]:active {
  background: rgba(255, 255, 255, 0.13);
}

/* Injected header controls (font −/+, theme, language toggle): a RESTING fill
 * instead of the hover-only background (invisible on touch), AND sized to
 * match the nav buttons (Article List / Metrics) so the whole top bar reads
 * as one family. The base rule pins a fixed 32px height + 1.05rem font; here
 * we drop that for the nav links' rem-based padding/text so they're the same
 * visual size and grow in lockstep with the font scaling. */
#admin-header-toolbar .admin-header-btn {
  background: rgba(0, 0, 0, 0.05) !important;
  height: auto !important;
  min-width: 2.4rem !important;        /* comfy tap target for the icon/+/- buttons */
  padding: 0.45rem 0.6rem !important;  /* == the nav links' tap target */
  font-size: 1rem !important;          /* == the nav links' text size */
  border-radius: 3px !important;       /* == the nav links' radius */
}
/* Day/night icon: the JS sets a fixed 17px attr — scale it with the button
 * font so it matches the cap-height of the +/- glyphs and the nav text. */
#admin-header-toolbar .admin-header-btn svg {
  width: 1.2em !important;
  height: 1.2em !important;
}
#admin-header-toolbar .admin-header-btn:active {
  background: rgba(0, 0, 0, 0.1) !important;
}
html[data-theme='dark'] #admin-header-toolbar .admin-header-btn {
  background: rgba(255, 255, 255, 0.07) !important;
}

/* Neutralise strichliste's hover-only card lift (var(--level3)) — it never
 * fires on touch and goes sticky after a tap. Hold our resting elevation. */
[class*="user-card_userCard"]:hover {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
}
html[data-theme='dark'] [class*="user-card_userCard"]:hover {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Guest / regular "line break" — a full-width rule the ui-overrides sorter drops
 * into the card grid (order-placed) between the guests and the regulars, so it's
 * obvious where the regular users begin. */
/* The strichliste card grid forces every auto row to a 90px minimum
 * (grid-auto-rows: minmax(90px, auto)) — which made the divider's OWN row 90px
 * tall (the big gap). Drop the row-min and re-assert the minimum on the card
 * LINKS instead, so card rows keep their height but the divider row collapses. */
[class*="layout_cardGrid"] {
  grid-auto-rows: minmax(0, auto) !important;
}
[class*="layout_cardGrid"] > a {
  min-height: 90px;
}
.admin-guest-divider {
  grid-column: 1 / -1;
  height: 0;
  margin: -6px 0 -2px; /* snug — pull the regulars up close to the line */
  border-top: 1px solid var(--border);
}

/* "ALL TRANSACTIONS" footer button under the per-user transaction list. It
 * shares strichliste's button_button class with "Pay", so scope tightly to the
 * flex row that follows the transaction grid: give it breathing room above (it
 * was jammed against the rows) + a subtle Fluent fill so it reads as tappable. */
[class*="user-details_grid"] + [class*="layout_flex"] {
  margin-top: 0.9rem !important;
}
[class*="user-details_grid"] + [class*="layout_flex"] > [class*="button_button"] {
  background: rgba(0, 0, 0, 0.05);
  border-radius: 3px;
  padding: 0.3rem 0.7rem;
}
html[data-theme='dark']
  [class*="user-details_grid"]
  + [class*="layout_flex"]
  > [class*="button_button"] {
  background: rgba(255, 255, 255, 0.07);
}
[class*="user-details_grid"]
  + [class*="layout_flex"]
  > [class*="button_button"]:active {
  background: rgba(0, 0, 0, 0.1);
}

/* ==================================================================
 * Transaction rows — alignment + undo affordance.
 * ================================================================== */

/* Fixed-width, right-aligned amount column so the type badges / article names
 * line up vertically down the whole list (instead of starting at a ragged x). */
[class*="transaction-list-item_grow"] {
  align-items: center; /* if the row is flex: vertically centre amount + desc */
}
[class*="transaction-list-item_grow"] > [class*="text_noWrap"] {
  display: inline-block;
  min-width: 4.7rem;
  text-align: right;
  vertical-align: middle; /* sit on the same line as the badge / article */
}
[class*="transaction-list-item_grow"] > [class*="text_ellipsis"] {
  vertical-align: middle;
}

/* Undo button on a deletable row: a full-row-height PILL (the "vertically
 * higher" ask — a taller tap target without getting wider or adding row
 * height). Lives in the right slot of the flex row, so align-self stretches it. */
[class*="transaction-list-item_grid"] > [class*="button_button"] {
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  padding: 0.5rem 1.4rem;
  min-width: 7rem; /* comfortable tap target (not tiny, not row-hogging) */
  background: rgba(0, 0, 0, 0.06);
  font-weight: 600;
  white-space: nowrap;
}
html[data-theme='dark']
  [class*="transaction-list-item_grid"]
  > [class*="button_button"] {
  background: rgba(255, 255, 255, 0.09);
}
[class*="transaction-list-item_grid"] > [class*="button_button"]:active {
  background: rgba(0, 0, 0, 0.12);
}

/* Breathing room above the footer credit line (was jammed under the content). */
[class*="footer_footer"] {
  margin-top: 3rem;
}

/* Card user-name: the card link colours its text brand-blue, which is low
 * contrast on the card surface. Force high contrast — off-black (light) /
 * off-white (dark), each with a faint blue hint. Balance keeps its green/red. */
[class*="user-card_userCard"] [class*="user-name_wrapper"] {
  color: #1b2735 !important; /* off-black, hint of blue */
}
html[data-theme='dark'] [class*="user-card_userCard"] [class*="user-name_wrapper"] {
  color: #e6edf6 !important; /* off-white, hint of blue */
}

/* ==================================================================
 * Fresh-purchase animation — the new top row expands IN with a highlight
 * (pushing the previous rows down), then the highlight fades out. The
 * .admin-tx-fresh class is added by ui-overrides.js once per confirmed buy.
 * ================================================================== */
@keyframes admin-tx-enter {
  0% { max-height: 0; opacity: 0; background-color: rgba(15, 108, 189, 0.32); }
  28% { max-height: 7rem; opacity: 1; background-color: rgba(15, 108, 189, 0.32); }
  100% { max-height: 7rem; opacity: 1; background-color: transparent; }
}
@keyframes admin-tx-enter-dark {
  0% { max-height: 0; opacity: 0; background-color: rgba(71, 158, 245, 0.34); }
  28% { max-height: 7rem; opacity: 1; background-color: rgba(71, 158, 245, 0.34); }
  100% { max-height: 7rem; opacity: 1; background-color: transparent; }
}
.admin-tx-fresh {
  overflow: hidden;
  animation: admin-tx-enter 1.8s ease-out;
}
html[data-theme='dark'] .admin-tx-fresh {
  animation: admin-tx-enter-dark 1.8s ease-out;
}

/* Pay button: strichliste fixes it to <body> with z-index 2147483000, so it
 * floats OVER the header when scrolling. Drop it below the header (z-index 200)
 * so it sits behind it. (The classless fixed <button> is the Pay button.) */
/* Pay button = the SumUp self-settle button (#sumup-settle-button, injected by
 * settle.js with inline styles: position:fixed, z-index 2.1e9, HEIGHT 56px).
 * Drop it BEHIND the header (z 200) and ~halve its height — the inline height
 * means these need !important to win. */
#sumup-settle-button {
  z-index: 199 !important;
  height: 30px !important;
  border-radius: 15px !important;
  padding: 0 0.9rem !important;
  font-size: 0.95rem !important;
}

/* Floating "value flies out of the balance" cue on an article purchase
 * (ui-overrides.js flyPurchaseValue): springs from the balance, swiftly moves
 * left while fading. Fixed-position copy, removed after it plays. */
@keyframes admin-fly-value {
  0% { opacity: 0; transform: translateX(0) scale(1); }
  8% { opacity: 1; transform: translateX(-3px) scale(1); }
  /* the cubic-bezier below does the fast launch / long deceleration; this stop
   * keeps the value readable through most of the glide, fading only at the end */
  80% { opacity: 1; transform: translateX(-180px) scale(0.58); }
  100% { opacity: 0; transform: translateX(-205px) scale(0.5); }
}
.admin-fly-value {
  position: fixed;
  z-index: 400;
  pointer-events: none;
  white-space: nowrap;
  font-weight: 800;
  color: var(--red, #c50f1f); /* font-size is set in JS to match the balance */
  /* slower + sharp fast-start / slow-end */
  animation: admin-fly-value 1.6s cubic-bezier(0.12, 0.86, 0.12, 1) forwards;
}
