/* ==========================================================================
   Toral Panel — Userside chrome (logo block, sidebar, header, menu bar, footer)
   Rendered by ToralPanel\Frontend\Userside\UI\Shell. Consumes only tokens
   from toral-userside-tokens.css — never hard-code a colour here.

   Structure it styles (rendered by PHP, not by Elementor):
     html[data-tp-us-theme][data-tp-us-nav][dir]
       body.tp-us-body
         .tp-us-app
           .tp-us-brand            (side layout only — logo block)
           .tp-us-side             (side layout only — sidebar)
           .tp-us-header           (always)
           .tp-us-topnav           (top layout only — menu bar)
           .tp-us-main             (scroll container)
             .tp-us-content        (widget surface = Elementor content)
             .tp-us-footer
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* Shared ground for both layouts: the panel shell and the auth pages.
   `body:has(.tp-us-app)` is a fallback: the shell class comes from a body_class
   filter, and if that ever misses the page, the presence of the app grid is
   proof enough that the chrome is on screen. Browsers without :has() simply
   ignore that selector and rely on the class. */
body.tp-us-body,
body.tp-us-body-auth,
body:has(.tp-us-app) {
  margin: 0;
  background: var(--tp-us-app-bg);
  color: var(--tp-us-text);
  font: 14px/1.65 var(--tp-us-font);
  -webkit-font-smoothing: antialiased;
}

/* The document itself never scrolls: the sidebar and the main column each
   scroll on their own, so the logo block and the header stay put.
   Height is in vh rather than 100% so it does not depend on <html>, which
   WordPress pushes down with a margin when the admin bar is showing. */
body.tp-us-body,
body:has(.tp-us-app) {
  /* 100vh is the LARGE viewport on a phone: it keeps the height the page
     would have with the browser bars hidden, so on iOS Safari and Samsung
     Internet the bottom of the grid - the footer - sits under the address
     bar and can never be scrolled to, because the body itself does not
     scroll. 100dvh follows the visible area instead; the 100vh line above
     stays as the fallback for browsers without dvh. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  padding: var(--tp-us-gap);
}

/* WordPress prints `html { margin-top: 32px !important }` for the admin bar
   (46px on narrow screens), so the app has to give that height back. */
body.tp-us-body.admin-bar { height: calc(100vh - 32px); height: calc(100dvh - 32px); }
@media screen and (max-width: 782px) {
  body.tp-us-body.admin-bar { height: calc(100vh - 46px); height: calc(100dvh - 46px); }
}

:where(.tp-us-body) :focus-visible {
  outline: 2px solid var(--tp-us-accent);
  outline-offset: 2px;
}

.tp-us-icon { flex: none; display: block; }

/* The user-agent's `[hidden] { display: none }` is a plain element rule, so any
   class rule below that sets `display` outranks it and the element stays
   visible. The chrome toggles `.hidden` from JS (menu search, drawer backdrop,
   dropdown panels), so those cases need it spelled out. */
.tp-us-navlink[hidden],
.tp-us-navgroup[hidden],
.tp-us-mail-badge[hidden],
.tp-us-menu-panel[hidden],
.tp-us-topsearch-panel[hidden],
.tp-us-toasts[hidden],
.tp-us-backdrop[hidden],
.tp-us-app[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   1. App grid
   -------------------------------------------------------------------------- */
.tp-us-app {
  display: grid;
  gap: var(--tp-us-gap);
  height: 100%;
  transition: grid-template-columns var(--tp-us-transition);
}

/* Side-menu themes: logo over sidebar, header over content. */
[data-tp-us-nav="side"] .tp-us-app {
  grid-template-columns: var(--tp-us-sidebar-w) minmax(0, 1fr);
  grid-template-rows: var(--tp-us-chrome-h) minmax(0, 1fr);
  grid-template-areas:
    "brand  header"
    "side   main";
}
html.tp-us-collapsed[data-tp-us-nav="side"] .tp-us-app {
  grid-template-columns: var(--tp-us-sidebar-wc) minmax(0, 1fr);
}

/* Top-menu themes: header, menu bar, then content. */
[data-tp-us-nav="top"] .tp-us-app {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: var(--tp-us-chrome-h) auto minmax(0, 1fr);
  grid-template-areas:
    "header"
    "topnav"
    "main";
}

.tp-us-brand  { grid-area: brand; }
.tp-us-side   { grid-area: side; }
.tp-us-header { grid-area: header; }
.tp-us-topnav { grid-area: topnav; }
.tp-us-main   { grid-area: main; }

/* Shell only prints the pieces that belong to the active layout, so these
   rules never normally match. They stay as a guard: if a page is served from
   a full-page cache written under the other theme, the stale chrome is hidden
   instead of stacking on top of the current one. */
[data-tp-us-nav="top"]  .tp-us-brand--side,
[data-tp-us-nav="top"]  .tp-us-side,
[data-tp-us-nav="side"] .tp-us-topnav,
[data-tp-us-nav="side"] .tp-us-brand--top { display: none; }

/* Golden Black: header and menu bar are one joined block, then a gap before
   the content (owner rule 4.3). */
[data-tp-us-theme="goldenblack"] .tp-us-app { row-gap: 0; }
[data-tp-us-theme="goldenblack"] .tp-us-main { margin-block-start: var(--tp-us-gap); }
[data-tp-us-theme="goldenblack"] .tp-us-header {
  border-start-start-radius: var(--tp-us-radius-xl);
  border-start-end-radius: var(--tp-us-radius-xl);
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}
[data-tp-us-theme="goldenblack"] .tp-us-topnav {
  border-start-start-radius: 0;
  border-start-end-radius: 0;
  border-end-start-radius: var(--tp-us-radius-xl);
  border-end-end-radius: var(--tp-us-radius-xl);
}

/* --------------------------------------------------------------------------
   2. Shared chrome surface (logo block, sidebar, header, menu bar)
   -------------------------------------------------------------------------- */
.tp-us-brand,
.tp-us-side,
.tp-us-topnav {
  position: relative;
  border-radius: var(--tp-us-radius-xl);
  background: var(--tp-us-chrome-bg);
  color: var(--tp-us-chrome-text);
  box-shadow: var(--tp-us-shadow);
}

/* Faint diagonal texture, drawn in CSS so no image asset is needed. */
.tp-us-brand::before,
.tp-us-side::before,
.tp-us-header::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    -45deg,
    var(--tp-us-chrome-stripe) 0,
    var(--tp-us-chrome-stripe) 1px,
    transparent 1px,
    transparent 13px
  );
}
.tp-us-header::before { background-image: repeating-linear-gradient(
    -45deg,
    var(--tp-us-header-stripe) 0,
    var(--tp-us-header-stripe) 1px,
    transparent 1px,
    transparent 13px
  );
}

/* --------------------------------------------------------------------------
   3. Logo block
   -------------------------------------------------------------------------- */
.tp-us-brand { overflow: hidden; }

.tp-us-brand-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  height: 100%;
  padding-inline: 20px;
  color: inherit;
  text-decoration: none;
}
.tp-us-brand-link:hover { text-decoration: none; }

/* A logo picture is centred in its block. The cropper fixes the shape of the
   picture, not its width relative to the block, so the leftover space has to
   be split evenly — left at the default `flex-start` it all collected on one
   side and the logo looked off-centre. Only the side-menu block does this:
   in the header the logo shares its row with the page title. */
.tp-us-brand--side .tp-us-brand-link--img { justify-content: center; }

/* Sidebar logo picture: less empty space around it, so it shows bigger.
   The 20px side padding and the 38px height cap left the logo small inside
   a 252 x 68 block. 10px of padding and a 52px cap still keep it inside the
   block (8px above and below on the 68px row) and the cropper's 4:1 shape
   (208 x 52) still fits the width. The collapsed rail keeps its own, more
   specific rules below; the header logo (top-menu themes) is untouched. */
.tp-us-brand--side .tp-us-brand-link--img { padding-inline: 10px; }
.tp-us-brand--side .tp-us-brand-img { max-height: 52px; }

/* Fallback mark, used until the admin uploads a logo image. */
.tp-us-brand-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--tp-us-radius-md);
  background: linear-gradient(135deg, var(--tp-us-b-500), var(--tp-us-b-600));
  color: #fff;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .5px;
}
[data-tp-us-theme="goldenblack"] .tp-us-brand-mark { color: var(--tp-us-on-accent); }

/* The admin can upload a logo of any size, so the image is boxed rather than
   trusted: the height is capped well under the 68px chrome row and the width
   can never exceed the block it sits in. `object-fit: contain` keeps the
   aspect ratio, so a tall or a very wide file both shrink to fit instead of
   stretching the header or being clipped by the block's overflow: hidden. */
.tp-us-brand-img {
  display: block;
  max-height: 38px;
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

.tp-us-brand-text {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: .3px;
  white-space: nowrap;
}
.tp-us-brand-text b { font-weight: 800; }

html.tp-us-collapsed .tp-us-brand-link { padding-inline: 8px; justify-content: center; }
html.tp-us-collapsed .tp-us-brand-text { display: none; }

/* Collapsed rail: the logo shrinks to fit the narrow block instead of being
   cropped by it. Keeping the block at full width while the sidebar collapses
   is not possible here — the logo block and the sidebar share one grid
   column — so the image scales down and stays whole. */
html.tp-us-collapsed .tp-us-brand-img {
  max-width: calc(var(--tp-us-sidebar-wc) - 16px);
  max-height: 34px;
}

/* Logo inside the header (top-menu themes) */
.tp-us-brand--top {
  display: flex;
  align-items: center;
  background: none;
  box-shadow: none;
  border-radius: 0;
}
.tp-us-brand--top::before { display: none; }
.tp-us-brand--top .tp-us-brand-link { padding-inline: 4px 8px; }
/* In the header the logo shares the row with the page title, so it also gets
   a hard width ceiling — an oversized upload must not push the title out. */
.tp-us-brand--top .tp-us-brand-img { max-width: 170px; max-height: 34px; }
@media (max-width: 640px) {
  .tp-us-brand--top .tp-us-brand-img { max-width: 110px; max-height: 28px; }
}

/* --------------------------------------------------------------------------
   4. Sidebar
   -------------------------------------------------------------------------- */
.tp-us-side {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 14px 12px 54px;
  overflow: hidden;
}
.tp-us-side > * { position: relative; }

/* Sunset pins a New Order call-to-action above the scrolling menu. */
.tp-us-cta {
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 44px;
  margin-bottom: 12px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-chrome-active);
  color: var(--tp-us-b-700);
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: var(--tp-us-shadow-sm);
  transition: transform var(--tp-us-transition), box-shadow var(--tp-us-transition);
}
.tp-us-cta:hover { transform: translateY(-1px); box-shadow: var(--tp-us-shadow); text-decoration: none; }
[data-tp-us-theme="sunset"] .tp-us-cta,
[data-tp-us-theme="sapphire"] .tp-us-cta { display: flex; }
/* Sapphire: yellow pill, blue text. */
[data-tp-us-theme="sapphire"] .tp-us-cta { background: var(--tp-us-pop); color: var(--tp-us-on-pop); }
html.tp-us-collapsed .tp-us-cta .tp-us-cta-text { display: none; }

/* Search */
.tp-us-search { flex: none; position: relative; margin-bottom: 14px; }

.tp-us-search-icon {
  position: absolute;
  inset-inline-start: 11px;
  top: 50%;
  transform: translateY(-50%);
  color: currentColor;
  opacity: .7;
  pointer-events: none;
}

.tp-us-search-input {
  width: 100%;
  height: 38px;
  padding-inline: 36px 12px;
  border: 1px solid var(--tp-us-chrome-line);
  border-radius: var(--tp-us-radius-md);
  background: rgba(255, 255, 255, .08);
  color: inherit;
  font: inherit;
  font-size: 13px;
  transition: border-color var(--tp-us-transition), background var(--tp-us-transition);
}
.tp-us-search-input::placeholder { color: currentColor; opacity: .6; }
.tp-us-search-input:focus {
  outline: none;
  border-color: var(--tp-us-b-400);
  background: rgba(255, 255, 255, .14);
}

html.tp-us-collapsed .tp-us-search-input { padding-inline: 12px; color: transparent; }
html.tp-us-collapsed .tp-us-search-input::placeholder { color: transparent; }
html.tp-us-collapsed .tp-us-search-icon { inset-inline-start: 50%; transform: translate(-50%, -50%); }
html.tp-us-collapsed[dir="rtl"] .tp-us-search-icon { transform: translate(50%, -50%); }

/* Nav list — the sidebar's own scroll area (independent of the content) */
.tp-us-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .2) transparent;
}
.tp-us-nav::-webkit-scrollbar { width: 6px; }
.tp-us-nav::-webkit-scrollbar-thumb {
  border-radius: var(--tp-us-radius-pill);
  background: rgba(255, 255, 255, .2);
}

.tp-us-navgroup {
  margin: 16px 0 6px;
  padding-inline: 12px;
  color: var(--tp-us-chrome-group);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  white-space: nowrap;
}
.tp-us-navgroup:first-child { margin-top: 0; }
html.tp-us-collapsed .tp-us-navgroup { padding-inline: 0; text-align: center; font-size: 0; }
html.tp-us-collapsed .tp-us-navgroup::after {
  content: "";
  display: block;
  height: 1px;
  margin: 10px 16px;
  background: var(--tp-us-chrome-line);
}

.tp-us-navlink {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 3px;
  padding: 10px 12px;
  border-radius: var(--tp-us-radius-md);
  color: inherit;
  font-size: 13.5px;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--tp-us-transition), color var(--tp-us-transition),
              transform var(--tp-us-transition);
}
.tp-us-navlink:hover {
  background: var(--tp-us-chrome-hover);
  text-decoration: none;
}
[dir="ltr"] .tp-us-navlink:hover { transform: translateX(2px); }
[dir="rtl"] .tp-us-navlink:hover { transform: translateX(-2px); }

.tp-us-navlink.is-active {
  background: var(--tp-us-chrome-active);
  color: var(--tp-us-on-accent);
  font-weight: 600;
}
[data-tp-us-theme="royal"]   .tp-us-navlink.is-active,
[data-tp-us-theme="emerald"] .tp-us-navlink.is-active,
[data-tp-us-theme="darkenblue"] .tp-us-navlink.is-active { color: #fff; }

/* Active marker on the inline-start edge. */
.tp-us-navlink.is-active::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 22px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-b-200);
}
[data-tp-us-theme="sunset"] .tp-us-navlink.is-active::before { background: var(--tp-us-b-600); }

.tp-us-navlink.is-danger:hover { background: rgba(239, 68, 68, .24); color: #fff; }

.tp-us-navicon { flex: none; display: grid; place-items: center; width: 22px; }
.tp-us-navtext { flex: 1; overflow: hidden; text-overflow: ellipsis; }

.tp-us-navbadge {
  flex: none;
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 19px;
  padding-inline: 6px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-red);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

html.tp-us-collapsed .tp-us-navlink { justify-content: center; padding-inline: 0; }
html.tp-us-collapsed .tp-us-navtext { display: none; }
html.tp-us-collapsed .tp-us-navlink.is-active::before { display: none; }
html.tp-us-collapsed .tp-us-navbadge {
  position: absolute;
  top: 4px;
  inset-inline-end: 10px;
  min-width: 16px;
  height: 16px;
  padding-inline: 4px;
  font-size: 9.5px;
}

/* Tooltip for the collapsed rail */
html.tp-us-collapsed .tp-us-navlink::after {
  content: attr(data-tp-label);
  position: absolute;
  inset-inline-start: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  padding: 5px 10px;
  border-radius: var(--tp-us-radius-sm);
  background: var(--tp-us-b-900);
  color: #fff;
  font-size: 12px;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--tp-us-transition);
}
html.tp-us-collapsed .tp-us-navlink:hover::after { opacity: 1; visibility: visible; }

.tp-us-nav-empty { margin: 6px 12px; font-size: 12.5px; opacity: .75; }

/* Collapse control pinned to the sidebar footer */
.tp-us-collapse {
  position: absolute;
  inset-block-end: 12px;
  inset-inline-end: 12px;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: var(--tp-us-radius-sm);
  background: rgba(255, 255, 255, .1);
  color: inherit;
  cursor: pointer;
  transition: background var(--tp-us-transition);
}
.tp-us-collapse:hover { background: rgba(255, 255, 255, .2); }
html.tp-us-collapsed .tp-us-collapse { inset-inline: 0; margin-inline: auto; }
html.tp-us-collapsed .tp-us-collapse .tp-us-icon { transform: scaleX(-1); }

/* --------------------------------------------------------------------------
   5. Header
   -------------------------------------------------------------------------- */
.tp-us-header {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--tp-us-chrome-h);
  padding-inline: 16px;
  border-radius: var(--tp-us-radius-xl);
  background: var(--tp-us-header-bg);
  color: var(--tp-us-header-text);
  box-shadow: var(--tp-us-shadow);
}

/* The start group takes the slack, so the clock and the end group stay
   together at the inline-end without justify-content: space-between —
   which would spread the clock away from them. */
.tp-us-header-start { flex: 1 1 auto; }

.tp-us-header-start,
.tp-us-header-end,
.tp-us-clock {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* Current page name (owner: "show the slug of the page the user is on"). */
.tp-us-page-title {
  margin: 0;
  padding-inline-start: 6px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tp-us-hbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 38px;
  height: 38px;
  padding-inline: 9px;
  border: 0;
  border-radius: var(--tp-us-radius-md);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--tp-us-transition);
}
.tp-us-hbtn:hover { background: var(--tp-us-header-hover); text-decoration: none; }
.tp-us-menu.is-open > .tp-us-hbtn { background: var(--tp-us-header-hover); }

.tp-us-clock-readout {
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Mail button: a shortcut to Tickets that shows how many of them have an
   unread reply. The count comes from Menu::unread_tickets(), the same source
   as the sidebar badge. */
.tp-us-mail { flex: none; }
.tp-us-mail-badge {
  position: absolute;
  inset-block-start: 3px;
  inset-inline-end: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding-inline: 4px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-red);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
/* A quiet pulse only while something is actually waiting to be read. */
.tp-us-mail.has-unread .tp-us-icon { animation: tp-us-mail-nudge 2.6s ease-in-out infinite; }
@keyframes tp-us-mail-nudge {
  0%, 84%, 100% { transform: translateY(0); }
  88%           { transform: translateY(-2px); }
  94%           { transform: translateY(1px); }
}


/* ==========================================================================
   Updates (announcements)
   --------------------------------------------------------------------------
   Two consumers, one stylesheet: the bell panel in this chrome AND the
   Updates widget on /updates. The `.tp-ann-*` block below is the shared
   announcement HEADER - the same markup both of them receive from
   Announcements\AnnouncementView - so it is defined once, here, in the file
   that is loaded on every Userside page. The widget stylesheet only adds the
   list and expand/collapse behaviour on top of it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Bell button
   -------------------------------------------------------------------------- */
.tp-us-updates { flex: none; }
.tp-us-bell { min-width: 38px; }
.tp-us-updates.has-unread .tp-us-icon { animation: tp-us-mail-nudge 2.6s ease-in-out infinite; }

/* --------------------------------------------------------------------------
   Bell panel - docked to the viewport edge, full height
   --------------------------------------------------------------------------
   Not a drop-down under the button: the agreed design is a tall panel at the
   far edge of the screen. `inset-inline-end` resolves to the LEFT edge in a
   right-to-left panel and to the RIGHT edge in a left-to-right one, which is
   exactly the rule the owner described, with no direction-specific override.

   The selector is DOUBLED (.tp-us-menu-panel.tp-us-updates-panel) on purpose.
   This panel also carries the generic .tp-us-menu-panel class so it inherits
   the shared open/close behaviour, and that generic rule — which pins every
   dropdown right under its own button — is defined further down this file.
   Two single-class rules have the same weight, so the later one would win and
   the panel would snap back under the bell. Doubling the class settles it
   regardless of where either rule sits. */
.tp-us-menu-panel.tp-us-updates-panel {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  inset-inline-start: auto;
  z-index: 120;
  display: flex;
  flex-direction: column;
  width: 400px;
  min-width: 0;
  max-width: 100vw;
  padding: 0;
  border: 0;
  border-radius: 0;
  border-inline-start: 1px solid var(--tp-us-border);
  background: var(--tp-us-surface);
  box-shadow: var(--tp-us-shadow-lg);
}

/* WordPress pins its admin bar over the top of the viewport, and a fixed
   panel starts behind it. Same offsets the body height already accounts for. */
body.admin-bar .tp-us-menu-panel.tp-us-updates-panel { inset-block-start: 32px; }
@media screen and (max-width: 782px) {
  body.admin-bar .tp-us-menu-panel.tp-us-updates-panel { inset-block-start: 46px; }
}

.tp-us-updates-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 0 12px;
  height: var(--tp-us-chrome-h);
  background: var(--tp-us-header-bg);
  color: var(--tp-us-header-text);
}
.tp-us-updates-head-title { flex: 1; font-size: 15px; font-weight: 700; }

.tp-us-updates-all {
  flex: none;
  padding: 6px 12px;
  border-radius: var(--tp-us-radius-pill);
  background: rgba(255, 255, 255, .18);
  color: inherit;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
}
.tp-us-updates-all:hover { background: rgba(255, 255, 255, .3); text-decoration: none; }

.tp-us-updates-close {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--tp-us-radius-md);
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: background var(--tp-us-transition);
}
.tp-us-updates-close:hover { background: rgba(255, 255, 255, .18); }

.tp-us-updates-list { flex: 1; overflow-y: auto; padding: 10px; }

.tp-us-updates-empty {
  margin: 0;
  padding: 26px 12px;
  color: var(--tp-us-text-dim);
  font-size: 12.5px;
  text-align: center;
}

/* One announcement. A card with a gap below it, so the rows read as separate
   items - the same spacing language the /updates list uses. */
.tp-us-updates-item {
  display: block;
  margin-block-end: 8px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-md);
  background: var(--tp-us-surface);
  color: var(--tp-us-text);
  cursor: pointer;
  transition: border-color var(--tp-us-transition), background var(--tp-us-transition);
}
.tp-us-updates-item:last-child { margin-block-end: 0; }
.tp-us-updates-item:hover { background: var(--tp-us-surface-2); border-color: var(--tp-us-border-strong); }
.tp-us-updates-item:focus-visible { outline: 2px solid var(--tp-us-accent); outline-offset: 2px; }

/* Unread carries a colour bar on the reading edge, so it survives any theme. */
.tp-us-updates-item.is-unread {
  background: var(--tp-us-surface-2);
  border-inline-start: 3px solid var(--tp-us-accent);
}

.tp-us-updates-item-main {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
}

.tp-us-updates-body {
  padding: 0 12px 10px;
  color: var(--tp-us-text-soft);
  font-size: 11.5px;
  line-height: 1.7;
}
.tp-us-updates-body :is(p, ul, ol) { margin: 4px 0; }
.tp-us-updates-body img { max-width: 100%; height: auto; }
.tp-us-updates-body a:not([class*="btn"]) { color: var(--tp-us-accent); }

/* --------------------------------------------------------------------------
   Shared announcement header (bell panel + /updates page)
   -------------------------------------------------------------------------- */
.tp-ann-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.tp-ann-code {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-inline: 9px 4px;
  padding-block: 3px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-surface-2);
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tp-ann-copy {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: var(--tp-us-radius-sm);
  background: transparent;
  color: var(--tp-us-text-dim);
  cursor: pointer;
  transition: color var(--tp-us-transition), background var(--tp-us-transition);
}
.tp-ann-copy:hover { background: var(--tp-us-surface-3); color: var(--tp-us-text); }
.tp-ann-copy.is-copied { color: var(--tp-us-green); }
.tp-ann-copy svg { stroke: currentColor; }

.tp-ann-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--tp-us-radius-pill);
  background: color-mix(in srgb, var(--tp-us-tone, var(--tp-us-accent)) 18%, transparent);
  color: var(--tp-us-tone, var(--tp-us-accent));
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.tp-ann-date {
  color: var(--tp-us-text-dim);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}

/* Order / view shortcuts: icons only, stacked, at the far end of the header
   row (order on top, view below). */
.tp-ann-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-inline-start: auto;
}
.tp-ann-iconbtn {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-sm);
  background: var(--tp-us-surface);
  color: var(--tp-us-text-soft);
  text-decoration: none;
  transition: background var(--tp-us-transition), color var(--tp-us-transition),
              border-color var(--tp-us-transition);
}
.tp-ann-iconbtn:hover {
  border-color: var(--tp-us-border-strong);
  text-decoration: none;
}
.tp-ann-iconbtn.is-primary {
  border-color: var(--tp-us-accent);
  background: var(--tp-us-accent);
}
.tp-ann-iconbtn.is-primary:hover { filter: brightness(1.08); }

/* These two buttons are <a> elements sitting inside a .tp-widget, and
   toral-userside-widgets.css paints widget links in the ACCENT colour — which
   is this button's own background. That is why the order icon was invisible.
   The cause is fixed at its source in that file (the link rule no longer
   matches anything with "btn" in its class), and the colour is pinned here as
   well so a theme- or Elementor-level `a { color: … }` cannot bring the bug
   back. `stroke` is painted explicitly because these glyphs are stroke-drawn
   from `currentColor` and vanish the moment the colour is repainted. */
.tp-ann-iconbtn               { color: var(--tp-us-text-soft) !important; }
.tp-ann-iconbtn:hover         { color: var(--tp-us-text) !important; }
.tp-ann-iconbtn.is-primary,
.tp-ann-iconbtn.is-primary:hover { color: var(--tp-us-on-accent) !important; }

.tp-ann-iconbtn svg              { stroke: var(--tp-us-text-soft); }
.tp-ann-iconbtn:hover svg        { stroke: var(--tp-us-text); }
.tp-ann-iconbtn.is-primary svg,
.tp-ann-iconbtn.is-primary:hover svg { stroke: var(--tp-us-on-accent); }

.tp-ann-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.tp-ann-price,
.tp-ann-expiry {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.tp-ann-price-label,
.tp-ann-expiry-label { color: var(--tp-us-text-dim); font-weight: 600; }
.tp-ann-price-old    { color: var(--tp-us-text-soft); text-decoration: line-through; }
.tp-ann-price-new    { color: var(--tp-us-text); font-weight: 700; }
.tp-ann-expiry-value { color: var(--tp-us-text); font-weight: 700; }
/* Logical rotation: the arrow has to point with the text, not against it. */
.tp-ann-price-arrow  { display: inline-block; color: var(--tp-us-text-dim); }
[dir="rtl"] .tp-ann-price-arrow { transform: scaleX(-1); }


.tp-us-caret { transition: transform var(--tp-us-transition); }
.tp-us-menu.is-open .tp-us-caret { transform: rotate(180deg); }

/* Balance chip + quick top-up */
.tp-us-balance {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding-inline: 12px 4px;
  border: 1px solid var(--tp-us-chrome-line);
  border-radius: var(--tp-us-radius-pill);
  background: rgba(255, 255, 255, .1);
  color: inherit;
  text-decoration: none;
  transition: background var(--tp-us-transition);
}
.tp-us-balance:hover { background: rgba(255, 255, 255, .18); text-decoration: none; }
.tp-us-balance-value { font-size: 13.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tp-us-balance-unit  { font-size: 11.5px; opacity: .8; }
.tp-us-balance-add {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-accent);
  color: var(--tp-us-on-accent);
  transition: transform var(--tp-us-transition);
}
.tp-us-balance:hover .tp-us-balance-add { transform: rotate(90deg); }
[data-tp-us-theme="sunset"] .tp-us-balance-add { background: #fff; color: var(--tp-us-b-700); }
[data-tp-us-theme="sapphire"] .tp-us-balance-add { background: var(--tp-us-pop); color: var(--tp-us-on-pop); }

/* Language picker: the globe sits with the other header buttons, so it needs
   no size of its own — only the dropdown positioning every .tp-us-menu gets,
   plus a tick on the language currently being read. */
.tp-us-lang-menu { position: relative; }
.tp-us-lang-menu .tp-us-menu-panel { min-width: 210px; }
.tp-us-cur-menu { position: relative; }
.tp-us-cur-menu .tp-us-menu-panel { min-width: 150px; }
.tp-us-menu-item.is-current { color: var(--tp-us-accent); font-weight: 600; }
.tp-us-menu-item.is-current .tp-us-icon { margin-inline-start: auto; }

/* Avatar: intentionally larger than the header, so it breaks out of the bar
   above and below (and a little past its inline-end edge). */
.tp-us-avatar-menu { margin-inline-start: 6px; z-index: 2; }

/* Top-menu themes: the menu bar sits directly under the header, so the avatar
   is kept level with the bar instead of overlapping the menu. */
[data-tp-us-nav="top"] { --tp-us-avatar: 62px; }

/* Sunset has no page padding, so an avatar centred on the header would spill
   off the top of the window. Here it only breaks out downwards. */
[data-tp-us-theme="sunset"] {
  --tp-us-avatar: 74px;
}
[data-tp-us-theme="sunset"] .tp-us-avatar-btn {
  align-self: flex-start;
  margin-block-start: 12px;
}
/* Lifts the header (and the avatar hanging below it) above the content. */
[data-tp-us-theme="sunset"] .tp-us-header { z-index: 3; }

.tp-us-avatar-btn {
  display: grid;
  place-items: center;
  width: var(--tp-us-avatar);
  height: var(--tp-us-avatar);
  margin-inline-end: -6px;
  padding: 0;
  border: 3px solid var(--tp-us-app-bg);
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-chrome-bg);
  color: #fff;
  cursor: pointer;
  overflow: hidden;
  box-shadow: var(--tp-us-shadow);
  transition: transform var(--tp-us-transition), box-shadow var(--tp-us-transition);
}
.tp-us-avatar-btn:hover { transform: scale(1.05); box-shadow: var(--tp-us-shadow-lg); }
.tp-us-avatar-btn img { width: 100%; height: 100%; object-fit: cover; display: block; }
[data-tp-us-theme="sunset"] .tp-us-avatar-btn { border-color: var(--tp-us-surface); }

/* Customer level ring (Bronze and up). The existing border stays as a thin gap
   between the picture and the ring, so the ring reads on every theme. */
.tp-us-avatar-btn.tp-us-avatar-ring {
  box-shadow: 0 0 0 3px var(--tp-us-level), var(--tp-us-shadow);
}
.tp-us-avatar-btn.tp-us-avatar-ring:hover {
  box-shadow: 0 0 0 3px var(--tp-us-level), var(--tp-us-shadow-lg);
}

/* Customer level emblem pinned on the header picture. Positioned on the menu
   wrapper because the button itself clips its content (overflow: hidden). */
.tp-us-avatar-menu { position: relative; }
.tp-us-avatar-emblem {
  position: absolute;
  inset-block-end: -6px;
  inset-inline-end: -12px;
  z-index: 1;
  width: 32px;
  height: 32px;
  pointer-events: none;
}
[data-tp-us-nav="top"] .tp-us-avatar-emblem { width: 26px; height: 26px; inset-block-end: -3px; }

/* Emblem beside the name in the account dropdown. */
.tp-us-menu-user-emblem { flex: 0 0 46px; width: 46px; height: 46px; }

/* Customer level badge: account dropdown, Profile and Dashboard widgets. */
.tp-level-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 22px;
  margin-top: 4px;
  padding-inline: 10px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-level);
  color: var(--tp-us-level-on);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   6. Dropdown menus (shared by header and top nav)
   -------------------------------------------------------------------------- */
.tp-us-menu { position: relative; }

.tp-us-menu-panel {
  position: absolute;
  inset-block-start: calc(100% + 10px);
  inset-inline-end: 0;
  z-index: 60;
  min-width: 196px;
  padding: 6px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-lg);
  background: var(--tp-us-surface);
  color: var(--tp-us-text);
  box-shadow: var(--tp-us-shadow-lg);
}

.tp-us-menu-title {
  padding: 7px 10px 5px;
  color: var(--tp-us-text-dim);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.tp-us-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--tp-us-radius-sm);
  background: transparent;
  color: var(--tp-us-text);
  font: inherit;
  font-size: 13px;
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--tp-us-transition);
}
.tp-us-menu-item:hover { background: var(--tp-us-surface-3); text-decoration: none; }
.tp-us-menu-item.is-danger { color: var(--tp-us-red); }
.tp-us-menu-item.is-danger:hover { background: rgba(239, 68, 68, .1); }
.tp-us-menu-item-text { flex: 1; }

.tp-us-menu-check {
  flex: none;
  width: 15px;
  height: 15px;
  border: 2px solid var(--tp-us-border-strong);
  border-radius: var(--tp-us-radius-pill);
  transition: border-color var(--tp-us-transition), background var(--tp-us-transition);
}
.tp-us-menu-item.is-selected .tp-us-menu-check {
  border-color: var(--tp-us-accent);
  background: var(--tp-us-accent);
  box-shadow: inset 0 0 0 2.5px var(--tp-us-surface);
}

.tp-us-menu-sep { height: 1px; margin: 5px 6px; background: var(--tp-us-border); }

.tp-us-menu-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 10px;
}
.tp-us-menu-user-name { font-size: 13.5px; font-weight: 700; }
.tp-us-menu-user-mail { font-size: 11.5px; color: var(--tp-us-text-dim); }

/* --------------------------------------------------------------------------
   7. Top menu bar (Emerald, Golden Black)
   -------------------------------------------------------------------------- */
.tp-us-topnav {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--tp-us-topnav-h);
  padding-inline: 12px;
  overflow: visible;
}

.tp-us-topnav-list {
  flex: 1;
  display: flex;
  align-items: center;
  /* Centred inside the bar (owner request). Auto margins on the first and last
     child do the centring rather than `justify-content: center`, because with
     justify-content the overflowing start of a scrolling row becomes
     unreachable. Auto margins collapse to 0 once the row is full, so the list
     simply scrolls from its start edge. */
  gap: 6px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.tp-us-topnav-list::-webkit-scrollbar { display: none; }
.tp-us-topnav-list > :first-child { margin-inline-start: auto; }
.tp-us-topnav-list > :last-child  { margin-inline-end: auto; }

/* The "More" dropdown sits outside the scrolling list so its panel is not
   clipped by that list's overflow. */
.tp-us-topmore { flex: none; }

.tp-us-toplink {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: none;
  height: 36px;
  padding-inline: 14px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-chrome-hover);
  color: inherit;
  font-size: 13.5px;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--tp-us-transition), color var(--tp-us-transition),
              transform var(--tp-us-transition);
}
.tp-us-toplink:hover { background: var(--tp-us-header-hover); transform: translateY(-1px); text-decoration: none; }
.tp-us-toplink.is-active {
  background: var(--tp-us-chrome-active);
  color: var(--tp-us-on-accent);
  font-weight: 600;
}
[data-tp-us-theme="emerald"] .tp-us-toplink.is-active { color: #fff; }

/* Collapsed search: an icon that opens a popover (owner's top-menu rule). */
.tp-us-topsearch { position: relative; flex: none; }
.tp-us-topsearch-btn {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-chrome-hover);
  color: inherit;
  cursor: pointer;
  transition: background var(--tp-us-transition);
}
.tp-us-topsearch-btn:hover { background: var(--tp-us-header-hover); }

.tp-us-topsearch-panel {
  position: absolute;
  inset-block-start: calc(100% + 10px);
  inset-inline-end: 0;
  z-index: 60;
  width: 290px;
  padding: 8px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-lg);
  background: var(--tp-us-surface);
  box-shadow: var(--tp-us-shadow-lg);
}
.tp-us-topsearch-panel input {
  width: 100%;
  height: 38px;
  padding-inline: 12px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-md);
  background: var(--tp-us-surface-2);
  color: var(--tp-us-text);
  font: inherit;
  font-size: 13px;
}
.tp-us-topsearch-panel input:focus { outline: none; border-color: var(--tp-us-accent); }

/* --------------------------------------------------------------------------
   8. Main column: content surface + footer, one scroll area
   -------------------------------------------------------------------------- */
.tp-us-main {
  display: flex;
  flex-direction: column;
  gap: var(--tp-us-gap);
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--tp-us-border-strong) transparent;
}
.tp-us-main::-webkit-scrollbar { width: 9px; }
.tp-us-main::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-border-strong);
  background-clip: content-box;
}

/* This is the element Elementor renders the page's widgets into.
   min-width: 0 is required: without it a wide child (the orders table sets
   min-width: 900px) stretches the flex item and pushes the whole page out of
   the viewport on a phone instead of scrolling inside its own box. */
.tp-us-content {
  flex: 1 0 auto;
  min-width: 0;
  padding: 22px;
  border-radius: var(--tp-us-radius-xl);
  background: var(--tp-us-surface);
  box-shadow: var(--tp-us-shadow);
}

/* Footer: thin, not fixed, sits after the content and scrolls with it. */
.tp-us-footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: var(--tp-us-footer-h);
  padding: 6px 18px;
  border-radius: var(--tp-us-radius-xl);
  background: var(--tp-us-surface);
  color: var(--tp-us-text-soft);
  font-size: 12.5px;
  box-shadow: var(--tp-us-shadow-sm);
}
[data-tp-us-theme="sunset"] .tp-us-footer { border-top: 1px solid var(--tp-us-border); box-shadow: none; }

.tp-us-footer-links { display: flex; align-items: center; gap: 6px; }

.tp-us-footer-link {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--tp-us-radius-pill);
  color: var(--tp-us-text-soft);
  text-decoration: none;
  transition: background var(--tp-us-transition), color var(--tp-us-transition),
              transform var(--tp-us-transition);
}
.tp-us-footer-link:hover {
  background: var(--tp-us-accent-soft);
  color: var(--tp-us-accent);
  transform: translateY(-1px);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   9. Mobile
   -------------------------------------------------------------------------- */
.tp-us-hamburger { display: none; }

.tp-us-backdrop {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgba(0, 0, 0, .5);
  backdrop-filter: blur(2px);
}

@media (max-width: 1200px) {
  :root { --tp-us-sidebar-w: 226px; }
}

@media (max-width: 991px) {
  body.tp-us-body { padding: 8px; }
  /* iPhone home-indicator strip: without this the last few pixels of the
     footer sit under it. Browsers without env() keep the 8px above. */
  body.tp-us-body { padding-block-end: calc(8px + env(safe-area-inset-bottom, 0px)); }
  [data-tp-us-theme="sunset"] body.tp-us-body { padding: 0; }

  [data-tp-us-nav="side"] .tp-us-app,
  html.tp-us-collapsed[data-tp-us-nav="side"] .tp-us-app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--tp-us-chrome-h) minmax(0, 1fr);
    grid-template-areas: "header" "main";
  }

  /* The sidebar becomes an off-canvas drawer with the logo block on top. */
  [data-tp-us-nav="side"] .tp-us-brand--side,
  [data-tp-us-nav="side"] .tp-us-side {
    position: fixed;
    z-index: 50;
    inset-inline-start: 8px;
    width: var(--tp-us-sidebar-w);
    max-width: calc(100vw - 60px);
    transform: translateX(calc((var(--tp-us-sidebar-w) + 24px) * -1));
    transition: transform var(--tp-us-transition);
  }
  [dir="rtl"][data-tp-us-nav="side"] .tp-us-brand--side,
  [dir="rtl"][data-tp-us-nav="side"] .tp-us-side {
    transform: translateX(calc(var(--tp-us-sidebar-w) + 24px));
  }
  [data-tp-us-nav="side"] .tp-us-brand--side { top: 8px; height: var(--tp-us-chrome-h); }
  [data-tp-us-nav="side"] .tp-us-side { top: calc(var(--tp-us-chrome-h) + 16px); bottom: 8px; }

  html.tp-us-drawer [data-tp-us-nav="side"] .tp-us-brand--side,
  html.tp-us-drawer[data-tp-us-nav="side"] .tp-us-brand--side,
  html.tp-us-drawer[data-tp-us-nav="side"] .tp-us-side { transform: translateX(0); }

  /* The rail never collapses in drawer mode. */
  html.tp-us-collapsed .tp-us-brand-text,
  html.tp-us-collapsed .tp-us-navtext,
  html.tp-us-collapsed .tp-us-cta .tp-us-cta-text { display: initial; }
  html.tp-us-collapsed .tp-us-navlink { justify-content: flex-start; padding-inline: 12px; }
  html.tp-us-collapsed .tp-us-navlink::after { display: none; }
  html.tp-us-collapsed .tp-us-search-input { padding-inline: 36px 12px; color: inherit; }
  html.tp-us-collapsed .tp-us-search-icon { inset-inline-start: 11px; transform: translateY(-50%); }

  .tp-us-collapse { display: none; }
  /* Only side-menu themes have a drawer to open. */
  [data-tp-us-nav="side"] .tp-us-hamburger { display: inline-flex; }
  .tp-us-page-title { font-size: 15.5px; }
}

/* Phones: the header grows one short row so the date stays visible instead of
   being dropped, and the chrome shrinks to fit a 360px screen. */
@media (max-width: 640px) {
  :root,
  [data-tp-us-nav="top"],
  [data-tp-us-theme="sunset"] { --tp-us-chrome-h: 92px; --tp-us-avatar: 46px; }

  .tp-us-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "start end"
      "clock clock";
    align-content: center;
    row-gap: 2px;
    padding: 6px 10px;
  }
  .tp-us-header-start { grid-area: start; }
  .tp-us-header-end   { grid-area: end; justify-content: flex-end; }
  .tp-us-clock        { grid-area: clock; justify-self: start; }
  .tp-us-clock .tp-us-hbtn { height: 28px; padding-inline: 6px; }
  .tp-us-clock-readout { font-size: 12px; }
  /* The clock sits at the START of its own row on a phone, but the shared
     dropdown is anchored to its inline-END edge, so it grew off-screen. Anchor
     it to the start edge instead, so it opens toward the middle of the screen. */
  .tp-us-clock .tp-us-menu-panel { inset-inline-end: auto; inset-inline-start: 0; }

  /* Only the mark stays; the wordmark has no room next to the balance chip. */
  .tp-us-brand--top .tp-us-brand-text { display: none; }
  .tp-us-page-title { display: none; }
  .tp-us-balance-unit { display: none; }
  .tp-us-balance { padding-inline: 10px 3px; height: 34px; }
  .tp-us-balance-add { width: 28px; height: 28px; }

  /* The mail and bell buttons keep their badge but shrink to the phone
     header height. */
  .tp-us-mail,
  .tp-us-bell { min-width: 32px; height: 32px; padding-inline: 5px; }
  .tp-us-mail-badge { inset-block-start: 0; inset-inline-end: -1px; min-width: 15px; height: 15px; font-size: 9.5px; }

  /* On a phone the docked panel takes the whole screen. */
  .tp-us-menu-panel.tp-us-updates-panel { width: 100vw; border-inline-start: 0; }
  .tp-us-updates-head { height: 56px; }
  .tp-ann-actions { flex-direction: row; }

  /* No room to bleed past the header on a phone. */
  .tp-us-avatar-btn {
    margin-inline-end: 0;
    margin-block-start: 0;
    align-self: center;
    border-width: 2px;
  }
  .tp-us-avatar-emblem { width: 20px; height: 20px; inset-block-end: -2px; inset-inline-end: -5px; }

  .tp-us-content { padding: 15px; }
  .tp-us-topnav { height: auto; padding: 8px 10px; }
  .tp-us-footer { flex-direction: column; gap: 4px; padding: 8px 12px; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
}

/* --------------------------------------------------------------------------
   10. Auth pages (login / signup / forgot password) — D5
   Same tokens, no sidebar/header chrome.
   -------------------------------------------------------------------------- */
/* Deliberately NOT a grid/centred layout.
   The login, signup and forgot-password pages are built by the admin in
   Elementor. Forcing a layout on <body> here would rearrange whatever they
   already built, so the auth pages only inherit the tokens, the background,
   the font and the colours (see the shared body rule at the top of this file).
   The classes below are opt-in: use them when you want the panel's own auth
   card instead of an Elementor-built form. */
.tp-us-auth {
  width: 100%;
  max-width: 396px;
  margin: 6vh auto;
}

.tp-us-auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  margin-bottom: 18px;
  color: var(--tp-us-text);
  font-size: 18px;
  font-weight: 500;
}
.tp-us-auth-brand b { font-weight: 800; }

.tp-us-auth-card {
  padding: 26px 24px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-xl);
  background: var(--tp-us-surface);
  box-shadow: var(--tp-us-shadow-lg);
}

.tp-us-auth-title { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
.tp-us-auth-sub   { margin: 0 0 20px; color: var(--tp-us-text-soft); font-size: 13px; }

.tp-us-field { margin-bottom: 14px; }
.tp-us-label { display: block; margin-bottom: 6px; font-size: 12.5px; font-weight: 600; }
.tp-us-auth-card .tp-input { display: block; width: 100%; }

.tp-us-auth-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
  font-size: 12.5px;
}
.tp-us-auth-card .tp-btn { width: 100%; height: 44px; }

.tp-us-auth-foot {
  margin: 18px 0 0;
  color: var(--tp-us-text-soft);
  font-size: 12.5px;
  text-align: center;
}
.tp-us-auth-foot a { color: var(--tp-us-accent); text-decoration: none; font-weight: 600; }
.tp-us-auth-foot a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   11. Toasts
   Replaces the browser's alert()/confirm() dialogs used by the current
   userside JS. Fixed to the viewport so it works in every layout.
   -------------------------------------------------------------------------- */
.tp-us-toasts {
  position: fixed;
  inset-block-end: 18px;
  inset-inline-end: 18px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(360px, calc(100vw - 32px));
  pointer-events: none;
}

.tp-us-toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--tp-us-border);
  border-inline-start: 3px solid var(--tp-us-text-dim);
  border-radius: var(--tp-us-radius-md);
  background: var(--tp-us-surface);
  color: var(--tp-us-text);
  font-size: 13.5px;
  box-shadow: var(--tp-us-shadow-lg);
  pointer-events: auto;
  animation: tp-us-toast-in 220ms cubic-bezier(.4, 0, .2, 1);
}
.tp-us-toast.is-leaving { animation: tp-us-toast-out 180ms ease-in forwards; }

.tp-us-toast--success { border-inline-start-color: var(--tp-us-green); }

/* Filled toasts (pale background in the tone's colour), asked for by the owner
   for the Wallet page messages. Opt-in per toast (the script adds the class),
   so every other toast keeps the surface background. */
.tp-us-toast--fill-success {
  background: color-mix(in srgb, var(--tp-us-green) 14%, var(--tp-us-surface));
  border-color: color-mix(in srgb, var(--tp-us-green) 34%, var(--tp-us-border));
}
.tp-us-toast--fill-error {
  background: color-mix(in srgb, var(--tp-us-red) 14%, var(--tp-us-surface));
  border-color: color-mix(in srgb, var(--tp-us-red) 34%, var(--tp-us-border));
}
.tp-us-toast--fill-warning {
  background: color-mix(in srgb, var(--tp-us-amber) 14%, var(--tp-us-surface));
  border-color: color-mix(in srgb, var(--tp-us-amber) 34%, var(--tp-us-border));
}
.tp-us-toast--fill-info {
  background: color-mix(in srgb, var(--tp-us-blue) 14%, var(--tp-us-surface));
  border-color: color-mix(in srgb, var(--tp-us-blue) 34%, var(--tp-us-border));
}
.tp-us-toast--error   { border-inline-start-color: var(--tp-us-red); }
.tp-us-toast--warning { border-inline-start-color: var(--tp-us-amber); }
.tp-us-toast--info    { border-inline-start-color: var(--tp-us-blue); }

.tp-us-toast__icon { flex: none; margin-top: 1px; }
.tp-us-toast--success .tp-us-toast__icon { color: var(--tp-us-green); }
.tp-us-toast--error   .tp-us-toast__icon { color: var(--tp-us-red); }
.tp-us-toast--warning .tp-us-toast__icon { color: var(--tp-us-amber); }
.tp-us-toast--info    .tp-us-toast__icon { color: var(--tp-us-blue); }

.tp-us-toast__body { flex: 1; min-width: 0; }
.tp-us-toast__title { font-weight: 700; }
.tp-us-toast__text  { color: var(--tp-us-text-soft); font-size: 12.5px; }

.tp-us-toast__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 0;
  border-radius: var(--tp-us-radius-sm);
  background: transparent;
  color: var(--tp-us-text-dim);
  cursor: pointer;
  transition: background var(--tp-us-transition), color var(--tp-us-transition);
}
.tp-us-toast__close:hover { background: var(--tp-us-surface-3); color: var(--tp-us-text); }

/* Confirmation toast (replaces confirm()) gets its own action row. */
.tp-us-toast__actions { display: flex; gap: 8px; margin-top: 10px; }
.tp-us-toast__actions .tp-btn { height: 32px; padding-inline: 14px; font-size: 12.5px; }

/* Confirmations are dialogs: centred, on their own backdrop, and above every
   widget modal (.tp-modal = 9999, new-order = 100000) so the buttons stay
   clickable while a modal is open. Empty host stays out of the way. */
.tp-us-confirms {
  position: fixed;
  inset: 0;
  z-index: 100010;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, .5);
  backdrop-filter: blur(2px);
}
.tp-us-confirms:empty { display: none; }

.tp-us-toast--confirm {
  width: min(400px, 100%);
  padding: 16px 18px;
  border-inline-start-width: 1px;
  border-top: 3px solid var(--tp-us-amber);
  border-radius: var(--tp-us-radius-xl);
}
.tp-us-toast--confirm.tp-us-toast--success { border-top-color: var(--tp-us-green); }
.tp-us-toast--confirm.tp-us-toast--error   { border-top-color: var(--tp-us-red); }
.tp-us-toast--confirm.tp-us-toast--info    { border-top-color: var(--tp-us-blue); }

@keyframes tp-us-toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes tp-us-toast-out {
  to { opacity: 0; transform: translateY(6px) scale(.98); }
}

@media (max-width: 640px) {
  .tp-us-toasts {
    inset-inline: 12px;
    inset-block-end: 12px;
    max-width: none;
  }
}

/* --------------------------------------------------------------------------
   12. Rewards shortcut (UI\Shell::rewards_button)
   A link, not a control: it opens the Rewards page. The dot only appears when
   a spin is actually waiting, and the gentle pulse stops for anyone who asked
   the system for reduced motion.
   -------------------------------------------------------------------------- */
.tp-us-rewardsfab {
  position: fixed;
  inset-block-end: 18px;
  inset-inline-start: 18px;
  z-index: 190;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--tp-us-on-accent);
  background: var(--tp-us-accent);
  box-shadow: var(--tp-us-shadow-lg);
  text-decoration: none;
  transition: transform var(--tp-us-transition), box-shadow var(--tp-us-transition);
}

.tp-us-rewardsfab:hover { transform: translateY(-2px); }
.tp-us-rewardsfab:focus-visible { outline: 2px solid var(--tp-us-accent); outline-offset: 3px; }

.tp-us-rewardsfab__dot {
  position: absolute;
  inset-block-start: 4px;
  inset-inline-end: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--tp-us-red);
  border: 2px solid var(--tp-us-surface);
}

.tp-us-rewardsfab.has-spin { animation: tp-us-fab-pulse 2.4s ease-in-out infinite; }

@keyframes tp-us-fab-pulse {
  0%, 100% { box-shadow: var(--tp-us-shadow-lg); }
  50%      { box-shadow: var(--tp-us-shadow-lg), 0 0 0 8px rgba(255, 255, 255, .08); }
}

@media (prefers-reduced-motion: reduce) {
  .tp-us-rewardsfab.has-spin { animation: none; }
}

@media (max-width: 640px) {
  .tp-us-rewardsfab {
    inset-block-end: 12px;
    inset-inline-start: 12px;
    width: 44px;
    height: 44px;
  }
}

/* --------------------------------------------------------------------------
   Pull to refresh (touch screens) — assets/js/toral-userside-pullrefresh.js
   --------------------------------------------------------------------------
   The round arrow that comes down from the top edge while the main column is
   pulled. Created by the script only on a touch screen, so desktop pages
   never carry it. Under the drawer backdrop (45) and every dialog. */
.tp-us-ptr {
  position: fixed;
  z-index: 44;
  top: env(safe-area-inset-top, 0px);
  left: 50%;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--tp-us-surface);
  color: var(--tp-us-text-soft);
  box-shadow: var(--tp-us-shadow);
  opacity: 0;
  transform: translate(-50%, -52px);
  pointer-events: none;
}
.tp-us-ptr.is-ready,
.tp-us-ptr.is-loading { color: var(--tp-us-accent); }
.tp-us-ptr.is-back { transition: transform 200ms ease, opacity 200ms ease; }
.tp-us-ptr.is-loading svg { animation: tp-us-ptr-spin 800ms linear infinite; }

@keyframes tp-us-ptr-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .tp-us-ptr.is-back { transition: none; }
  .tp-us-ptr.is-loading svg { animation: none; }
}
