/*
 * Shared styles for the /partners module.
 *
 * `.select-outline` is lifted verbatim from the pattern already used by
 * app/Views/products/create.php and admin/product_templates/form.php, so a select
 * sits beside an `input-group input-group-outline` text field without looking like
 * a different form system. It lives here rather than being copied a third time.
 *
 * Everything else is small module chrome. There is no Sass step on this project,
 * so this file is hand written and loaded by app/Views/partners/_head.php.
 */

.select-outline { position: relative; }
.select-outline select.form-select {
    border: 1px solid #d2d6da;
    border-radius: 0.5rem;
    padding: 0.5rem 2rem 0.5rem 0.75rem;
    font-size: 0.875rem;
    color: #344767;
    background-color: transparent;
    appearance: auto;
    width: 100%;
}
.select-outline select.form-select:focus {
    border-color: #5e72e4;
    box-shadow: 0 0 0 2px rgba(94,114,228,0.15);
    outline: none;
}
.select-outline label {
    position: absolute;
    top: -9px; left: 12px;
    font-size: 0.75rem;
    line-height: 1;
    color: #7b809a;
    background: #fff;
    padding: 0 4px;
    pointer-events: none;
    z-index: 1;
}
.select-outline:focus-within label { color: #5e72e4; }

/* Summary tiles across the top of a partner. Deliberately flat: these are counts a
   reader scans, not results that want emphasis. */
.pn-stat .pn-stat-label {
    font-size: 0.75rem;
    color: #7b809a;
    margin-bottom: 0.25rem;
}
.pn-stat .pn-stat-value {
    font-size: 1.375rem;
    font-weight: 700;
    color: #344767;
    line-height: 1.2;
}
.pn-stat .pn-stat-note { font-size: 0.7rem; }

/* A partner's code, shown wherever the submission link is referenced. */
.pn-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    background: #f0f1f4;
    color: #67748e;
    border-radius: 0.375rem;
    padding: 0.15rem 0.45rem;
}

/* Destructive actions are separated rather than sitting inline with everything
   else, so "delete partner" is never one mis-click from "save rates". */
.pn-danger { border: 1px solid #f5c2c7; }
.pn-danger .card-header { color: #b02a37; }

.pn-row-link { color: #344767; }
.pn-row-link:hover { color: #5e72e4; }

/* Rate inputs sit in a dense table, so they get a tighter box than a form field. */
.pn-rate-input {
    border: 1px solid #d2d6da;
    border-radius: 0.5rem;
    padding: 0.3rem 0.5rem;
    font-size: 0.8rem;
    text-align: right;
    width: 100%;
}
.pn-rate-input:focus {
    border-color: #5e72e4;
    box-shadow: 0 0 0 2px rgba(94,114,228,0.15);
    outline: none;
}

/* Copyable value: the submission code, which exists to be pasted into a link.
   user-select:all means one click takes the whole slug rather than the fragment
   between two hyphens, which is what a double click would otherwise give. */
.pn-copy { display:flex; align-items:stretch; max-width:100%; }
.pn-copy-value {
  flex:1; min-width:0;
  user-select:all; -webkit-user-select:all;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:0.8rem; color:#344767; background:#f6f7f9;
  border:1px solid #e3e6ec; border-right:0;
  border-radius:0.5rem 0 0 0.5rem;
  padding:0.4rem 0.6rem; overflow-x:auto; white-space:nowrap;
}
.pn-copy-btn {
  display:inline-flex; align-items:center; justify-content:center;
  border:1px solid #e3e6ec; border-radius:0 0.5rem 0.5rem 0;
  background:#fff; color:#8392ab; padding:0 0.6rem; cursor:pointer;
  transition:color .15s ease, background .15s ease;
}
.pn-copy-btn:hover { color:#5e72e4; background:#f6f7f9; }
.pn-copy-btn.is-copied { color:#2dce89; }
.pn-copy-btn .material-symbols-rounded { font-size:17px; }

/* A quiet action in a card head. Deliberately not a .btn: a themed button is far too
   loud beside a 0.85rem card title, and it also drags in the ripple element whose
   cleanup is fragile. Sits at the same grey as the head icon so it reads as chrome. */
.pn-card-action {
  margin-left:auto;
  display:inline-flex; align-items:center; gap:0.25rem;
  background:none; border:0; border-radius:0.375rem;
  padding:0.2rem 0.4rem;
  font-size:0.72rem; font-weight:600; color:#8392ab;
  cursor:pointer; white-space:nowrap;
  transition:color .15s ease, background .15s ease;
}
.pn-card-action:hover { color:#5e72e4; background:#f2f4f8; }
.pn-card-action .material-symbols-rounded { font-size:15px; }

/* Variants of the quiet card action.
   --inline drops the auto left margin, for one sitting in a card body or a row of
   siblings rather than pushed to the right of a card head.
   --danger keeps destructive actions red. Quiet is right for them - they should not
   invite a click - but the colour still has to say what they do before you read it. */
.pn-card-action--inline { margin-left:0; }
.pn-card-action--danger { color:#d64550; }
.pn-card-action--danger:hover { color:#b02a37; background:#fdf1f2; }

/* The action on a message that carries a link.
   Not a .btn, for the same reason .pn-card-action is not: the themed button drags in a
   ripple element whose cleanup is fragile. This replaced `btn btn-sm btn-outline-info`,
   which rendered as a large blue outlined pill - it fought the body copy above it and
   was the only blue action anywhere in a portal whose buttons are all black.
   Sized to sit under a paragraph rather than to lead a page. */
.pn-link-btn {
  display:inline-flex; align-items:center; gap:0.4rem;
  padding:0.5rem 1rem;
  border:0; border-radius:0.5rem;
  background-image:linear-gradient(195deg, #42424a 0%, #191919 100%);
  color:#fff; font-size:0.75rem; font-weight:600; letter-spacing:0.02em;
  text-decoration:none; white-space:nowrap;
  box-shadow:0 3px 5px -2px rgba(0,0,0,0.18);
  transition:box-shadow .15s ease, opacity .15s ease;
}
/* Colour repeated on both states: the theme restyles a:hover, so inheriting here would
   turn the label blue against the black fill. */
.pn-link-btn:hover, .pn-link-btn:focus {
  color:#fff; opacity:0.92;
  box-shadow:0 6px 12px -4px rgba(0,0,0,0.28);
}
.pn-link-btn .material-symbols-rounded { font-size:16px; }

/* Shop icon. A partner with none gets a tinted initial rather than a placeholder
   image: it needs no network call, cannot fail to load, and still gives the row
   something to scan against. */
.pn-icon {
  display:inline-flex; align-items:center; justify-content:center;
  flex:0 0 auto; overflow:hidden;
  background:#f0f1f4; color:#7b809a;
  font-weight:700; text-transform:uppercase;
  border:1px solid #e6e8ee; border-radius:0.5rem;
}
.pn-icon img { width:100%; height:100%; object-fit:contain; display:block; }

/* object-fit:contain, not cover: a logo cropped to fill a square loses the parts that
   identify it. Letterboxing inside the tile is the lesser evil. */
.pn-icon--sm { width:30px; height:30px; font-size:0.78rem; }
.pn-icon--lg { width:72px; height:72px; font-size:1.6rem; border-radius:0.75rem; }

.pn-icon-row { display:flex; align-items:center; gap:0.85rem; }

/* Six boxes for the sign-in code, rather than one text field with wide letter-spacing.
   A person reading a code off a phone is tracking their place in six characters, and
   discrete boxes give them somewhere to look. */
.pn-code-boxes { display:flex; gap:0.5rem; justify-content:center; }
.pn-code-box {
  width:100%; max-width:52px; height:58px;
  text-align:center; font-size:1.5rem; font-weight:700; color:#344767;
  font-variant-numeric: tabular-nums;
  border:1px solid #d2d6da; border-radius:0.6rem; background:#fff;
  transition:border-color .12s ease, box-shadow .12s ease;
  -moz-appearance:textfield;
}
.pn-code-box::-webkit-outer-spin-button,
.pn-code-box::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.pn-code-box:focus {
  /* Portal blue, not the staff indigo: these boxes only ever appear on the partner
     sign-in page, so they should look like the portal they belong to. */
  outline:none; border-color:#1A73E8; box-shadow:0 0 0 3px rgba(26,115,232,0.15);
}

/* Who you are signing in to, above the code boxes. */
.pn-signin-as {
  display:flex; align-items:center; gap:0.7rem; justify-content:center;
  background:#f6f7f9; border:1px solid #eef0f3; border-radius:0.6rem;
  padding:0.6rem 0.8rem;
}

/* The logo in the partner header sits on the coloured bar with no tile around it:
   a transparent logo already reads against that background, and a bordered box made
   it look like a placeholder waiting for an image rather than the shop's own mark.
   The fallback initial keeps the white text, which is legible on the bar unaided. */
.pn-icon--onDark {
  background:transparent;
  border:0;
  color:#fff;
}

/* ---------------------------------------------------------------------------
   Partner top bar. Two rows: brand and account on the first, navigation on the
   second. A sidebar would be more chrome than content for a portal this small,
   and putting the nav under the brand leaves room for it to grow.
   --------------------------------------------------------------------------- */
.pn-topbar { background:linear-gradient(195deg, #49a3f1, #1A73E8); box-shadow:0 4px 20px rgba(0,0,0,.14); }
.pn-topbar-main {
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; padding:0.7rem 0 0.55rem;
}
.pn-topbar-nav {
  display:flex; gap:0.35rem; flex-wrap:wrap;
  padding-bottom:0.4rem;
}

.pn-nav-link {
  color:rgba(255,255,255,0.78); font-size:0.8rem; font-weight:600;
  text-decoration:none; padding:0.3rem 0.7rem; border-radius:0.4rem;
  transition:color .15s ease, background .15s ease;
}
.pn-nav-link:hover { color:#fff; background:rgba(255,255,255,0.14); }
.pn-nav-link.active { color:#fff; background:rgba(255,255,255,0.22); }

/* Unread count on a nav link, in place of a bell.
   The partner pages deliberately do not load bootstrap.min.js, so a dropdown panel
   would mean hand-rolling one for a list that already has its own page. The count on
   the link does the same job with no JS at all.
   inline-flex with a fixed min-width so 1 and 9+ are the same width and the nav does
   not shuffle sideways as the count changes. */
.pn-nav-link { display:inline-flex; align-items:center; gap:0.35rem; }
.pn-nav-badge {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:1.15rem; height:1.15rem; padding:0 0.3rem;
  border-radius:999px; background:#fff; color:#344767;
  font-size:0.65rem; font-weight:700; line-height:1;
}

/* Account menu. Trigger is the store logo and name, like the staff navbar. */
.pn-menu { position:relative; }
.pn-menu-trigger {
  display:inline-flex; align-items:center; gap:0.55rem;
  background:none; border:0; cursor:pointer;
  padding:0.25rem 0.4rem; border-radius:0.5rem;
  color:#fff; transition:background .15s ease;
}
.pn-menu-trigger:hover,
.pn-menu-trigger[aria-expanded="true"] { background:rgba(255,255,255,0.14); }
.pn-menu-name { font-size:0.82rem; font-weight:600; }
.pn-menu-caret { font-size:18px; transition:transform .15s ease; }
.pn-menu-trigger[aria-expanded="true"] .pn-menu-caret { transform:rotate(180deg); }

/* The panel is a card, because that is what every other surface in this portal is:
   0.5rem radius and the theme's soft card shadow, tinted with the same blue the header
   uses rather than the neutral drop shadow. The accent throughout is the portal's info
   blue - NOT the indigo the staff settings screens use, which is what made an earlier
   version of this read as a piece of the internal portal that had wandered in. */
.pn-menu-panel {
  position:absolute; right:0; top:calc(100% + 0.5rem); z-index:1000;
  /* Matches the trigger: .pn-menu wraps only the button, so 100% of it IS the
     button's width. The min-width is the floor for narrow screens, where the store
     name is hidden and the trigger shrinks to an icon and a caret - without it the
     panel would collapse to about 70px and clip its own items. */
  width:100%; min-width:170px; padding:0.5rem;
  background:#fff; border:0; border-radius:0.5rem;
  box-shadow:0 2px 6px 0 rgba(26,115,232,.10),
             0 8px 24px -6px rgba(26,115,232,.22);
}
/* [hidden] loses to a display value from any utility class, so state it here. */
.pn-menu-panel[hidden] { display:none; }

.pn-menu-item {
  display:flex; align-items:center; gap:0.6rem;
  padding:0.55rem; border-radius:0.5rem;
  font-size:0.85rem; font-weight:500; color:#344767; text-decoration:none;
  transition:background .15s ease, color .15s ease;
}
.pn-menu-item:hover { background:rgba(26,115,232,.08); color:#1A73E8; }
.pn-menu-item .material-symbols-rounded { font-size:19px; color:#8392ab; }
.pn-menu-item:hover .material-symbols-rounded { color:#1A73E8; }

/* ---------------------------------------------------------------------------
   Partner portal palette overrides.
   `.pn-portal` is on <body> for every partner-facing page and nowhere else, so
   these reach the partner side without touching the staff /partners module that
   shares the same classes.

   The two portals use different accents on purpose: the staff screens sit beside
   /admin/settings and take its indigo, the partner portal takes the info blue of
   its own header. A shared component picking one of them for both is what makes a
   page read as belonging to the wrong application.
   --------------------------------------------------------------------------- */
.pn-portal .pn-card-action:hover { color:#1A73E8; background:rgba(26,115,232,.08); }
.pn-portal .select-outline select.form-select:focus {
  border-color:#1A73E8; box-shadow:0 0 0 2px rgba(26,115,232,.15);
}
.pn-portal .select-outline:focus-within label { color:#1A73E8; }

/* ---------------------------------------------------------------------------
   Badges. Flat tint with same-hue text rather than the theme's gradient pills,
   matching the treatment used on /support: at the density of a table, a row of
   saturated gradients competes with the data it is meant to annotate.
   --------------------------------------------------------------------------- */
.pn-badge {
  display:inline-block; font-size:.65rem; font-weight:700;
  padding:.2rem .55rem; border-radius:20px; white-space:nowrap;
  text-transform:uppercase; letter-spacing:.02em;
}
.pn-badge--neutral { background:#f0f2f5; color:#67748e; }
.pn-badge--blue    { background:#e3f2fd; color:#1565C0; }
.pn-badge--green   { background:#e8f5e9; color:#2e7d32; }
.pn-badge--amber   { background:#fff4e5; color:#b26a00; }
.pn-badge--red     { background:#fdecea; color:#c62828; }
.pn-badge--dark    { background:#e4e7ec; color:#3b4559; }

/* The whole row is a link to the partner. The name stays an anchor underneath, so
   keyboard navigation and middle-click still work without any of this. */
.partner-row { cursor:pointer; }
.partner-row:hover { background:#f8f9fa; }

/* Read-only field: label above value.
   The label was previously the same size as the value and differed only in colour,
   which at a glance made "Contact name" and the name itself read as one block of
   text. Same treatment as `.set-input-label` on the settings screens: smaller,
   uppercase and tracked, so it registers as a caption rather than as content. */
.pn-field { margin-bottom:0.9rem; }
.pn-field:last-child { margin-bottom:0; }
.pn-field-label {
  display:block; margin-bottom:0.15rem;
  font-size:0.65rem; font-weight:600; text-transform:uppercase;
  letter-spacing:0.03em; color:#8392ab;
}
.pn-field-value { font-size:0.875rem; color:#344767; }
.pn-field-value--empty { color:#a6adbb; }

/* --------------------------------------------------------------- Messages inbox

   List plus reading pane, the shape a mail client uses. Two panes side by side on a
   wide screen; on a narrow one the list is the page and picking a message swaps the
   reader in over it, with a Back control, rather than trying to fit both.

   Written here rather than inline in the view: it is enough CSS to be worth the
   filemtime cache-buster the layout already applies to this file. */

.pn-inbox {
  background:#fff; border-radius:0.75rem;
  box-shadow:0 2px 6px -1px rgba(0,0,0,.06), 0 2px 4px -1px rgba(0,0,0,.03);
  overflow:hidden;
}

/* Toolbar: segment filters on the left, count on the right. */
.pn-inbox-bar {
  display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;
  padding:0.7rem 0.9rem; border-bottom:1px solid #eef0f3;
}
.pn-seg { display:flex; gap:0.25rem; }
.pn-seg-btn {
  border:0; background:none; cursor:pointer;
  font-size:0.75rem; font-weight:600; color:#8392ab;
  padding:0.3rem 0.65rem; border-radius:0.45rem;
  display:inline-flex; align-items:center; gap:0.35rem;
  transition:background .15s ease, color .15s ease;
}
.pn-seg-btn:hover { background:#f4f6f9; color:#344767; }
.pn-seg-btn.is-active { background:#eceffd; color:#3b4bb8; }
.pn-seg-count {
  font-size:0.65rem; font-weight:700; line-height:1;
  background:#e4e7ec; color:#3b4559; border-radius:999px; padding:0.15rem 0.35rem;
}
.pn-seg-btn.is-active .pn-seg-count { background:#3b4bb8; color:#fff; }

/* Two panes. The list is a fixed column so message titles keep a predictable
   truncation point rather than reflowing with the reader's content. */
.pn-inbox-panes { display:flex; min-height:26rem; }
.pn-inbox-list {
  width:22rem; flex-shrink:0; border-right:1px solid #eef0f3;
  margin:0; padding:0; list-style:none;
  max-height:34rem; overflow-y:auto;

  /* Scroll shadows. With a long list the container clips the last row mid-way, which on its
     own reads as a rendering fault rather than as "there is more below". The two `local`
     gradients are white covers that scroll with the content; the two `scroll` radials are the
     shadows underneath, so a shadow only shows on the edge that actually has more content
     past it and disappears when you reach either end. */
  background:
    linear-gradient(#fff 30%, rgba(255,255,255,0)) top    / 100% 22px no-repeat local,
    linear-gradient(rgba(255,255,255,0), #fff 70%) bottom / 100% 22px no-repeat local,
    radial-gradient(farthest-side at 50% 0,    rgba(52,71,103,.10), transparent) top    / 100% 9px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, rgba(52,71,103,.10), transparent) bottom / 100% 9px no-repeat scroll;
}
.pn-inbox-reader { flex:1; min-width:0; }

/* A message row. The whole row is one button so it is reachable by keyboard and
   announced once, not as a pile of separate controls. */
.pn-msg {
  display:flex; gap:0.6rem; width:100%; text-align:left;
  background:none; border:0; cursor:pointer; color:inherit;
  padding:0.7rem 0.85rem; border-bottom:1px solid #f4f6f9;
  border-left:3px solid transparent;
  transition:background .12s ease;
}
.pn-msg:hover { background:#fafbfc; }
.pn-msg:focus-visible { outline:2px solid #5e72e4; outline-offset:-2px; }
.pn-msg.is-selected { background:#f5f7ff; border-left-color:#5e72e4; }
.pn-msg.is-hidden { display:none; }

/* The dot is the unread marker and keeps its space when read, so titles stay on one
   vertical line and the list does not jitter as messages are opened. */
.pn-msg-dot {
  flex-shrink:0; width:8px; height:8px; border-radius:50%;
  background:transparent; margin-top:0.32rem;
}
.pn-msg.is-unread .pn-msg-dot { background:#5e72e4; }

.pn-msg-main { flex:1; min-width:0; }

/* Top line of a row: subject left, date right. The subject takes the slack and truncates,
   which is what keeps a long one from pushing the date out of the fixed-width column. */
.pn-msg-top { display:flex; align-items:baseline; gap:0.5rem; }
.pn-msg-title {
  flex:1; min-width:0; font-size:0.82rem; color:#344767; font-weight:500;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.pn-msg.is-unread .pn-msg-title { font-weight:700; }
.pn-msg-date { flex-shrink:0; font-size:0.68rem; color:#adb5bd; }
.pn-msg.is-unread .pn-msg-date { color:#5e72e4; font-weight:600; }

/* Announcement marker. Only on the few rows that carry the flag, rather than another chip on
   every row, which is the thing the type badge got wrong. The row keeps a faint tint so an
   announcement block reads as one group at the top of the list. */
/* `align-self:center` because the row is a baseline-aligned flex line, and an icon glyph has
   no baseline worth sharing with text: sitting it on one hangs the icon above the title and
   date beside it. Centring it in the line is what actually lines it up. `line-height:1` for
   the same reason as in the reader - a Material Symbol's box is taller than its glyph. */
.pn-msg-announce {
  flex-shrink:0; align-self:center; line-height:1;
  font-size:15px; color:#fb6340;
}
.pn-msg.is-announcement { background:#fffaf7; }
.pn-msg.is-announcement:hover { background:#fff5ef; }
/* Selection still wins: it is the state the partner just acted on. */
.pn-msg.is-announcement.is-selected { background:#f5f7ff; }

/* The announcement label and the date share a line, and they have to sit level.
   `.pn-reader-announce` is an inline-flex box whose height is driven by the 14px icon inside
   it, which is taller than the 0.72rem text beside it. Left as inline content, the browser
   lines the box up on ITS baseline, and the label ends up riding above the date. Making the
   parent a flex row and centring both children takes the icon's height out of it. */
.pn-reader-date {
  display:flex; align-items:center; flex-wrap:wrap; gap:0.5rem;
  font-size:0.72rem; color:#adb5bd;
}
.pn-reader-announce {
  display:inline-flex; align-items:center; gap:0.2rem;
  color:#fb6340; font-weight:600;
}
/* Matched to the text it sits with so the two optical weights agree; the icon's own box is
   taller than its glyph, which is why line-height is pinned rather than left to inherit. */
.pn-reader-announce .material-symbols-rounded { font-size:14px; line-height:1; }

/* One line of the body, the way a mail list previews a message. */
.pn-msg-snippet {
  display:block; margin-top:0.15rem;
  font-size:0.72rem; color:#8392ab; line-height:1.4;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* Reading pane. */
.pn-reader { padding:1.4rem 1.5rem; }
.pn-reader-head { border-bottom:1px solid #f2f4f7; padding-bottom:0.9rem; margin-bottom:1.1rem; }
.pn-reader-title { font-size:1.05rem; font-weight:700; color:#344767; margin:0 0 0.35rem; line-height:1.35; }

/* Rich text. The body is sanitised HTML now, so the elements the allowlist permits each
   need a resting style; without these a list renders with browser-default indentation
   that does not line up with the paragraphs above it. */
.pn-reader-copy { font-size:0.9rem; color:#525f7f; line-height:1.7; }
.pn-reader-copy > *:first-child { margin-top:0; }
.pn-reader-copy > *:last-child { margin-bottom:0; }
.pn-reader-copy p { margin:0 0 0.85rem; }
.pn-reader-copy ul, .pn-reader-copy ol { margin:0 0 0.85rem; padding-left:1.35rem; }
.pn-reader-copy li { margin-bottom:0.3rem; }
.pn-reader-copy a { color:#5e72e4; text-decoration:underline; }
.pn-reader-copy blockquote {
  margin:0 0 0.85rem; padding:0.35rem 0 0.35rem 0.9rem;
  border-left:3px solid #e4e7ec; color:#67748e;
}
.pn-reader-copy strong, .pn-reader-copy b { color:#344767; font-weight:700; }

.pn-reader-empty { padding:4rem 1.5rem; text-align:center; color:#8392ab; }
.pn-reader-empty .material-symbols-rounded { font-size:40px; color:#c9d0d8; }

/* Back is the narrow-screen affordance only; on a wide screen both panes are up. */
.pn-reader-back {
  display:none; align-items:center; gap:0.3rem;
  border:0; background:none; cursor:pointer; padding:0 0 0.8rem;
  font-size:0.75rem; font-weight:600; color:#5e72e4;
}

@media (max-width: 991.98px) {
  .pn-inbox-panes { display:block; min-height:0; }
  .pn-inbox-list { width:auto; border-right:0; max-height:none; }
  .pn-inbox-reader { display:none; }
  /* Reading swaps the panes over rather than stacking them, so a long message does
     not push the list a screen and a half away. */
  .pn-inbox.is-reading .pn-inbox-list { display:none; }
  .pn-inbox.is-reading .pn-inbox-reader { display:block; }
  .pn-reader-back { display:inline-flex; }
}
