/* ==========================================================================
   BOLDMAC Training Center - interface styles
   --------------------------------------------------------------------------
   Navy and gold, matching the BOLDMAC myHub intranet so the portal reads as
   part of the same family rather than a separate system.

   Plain CSS with custom properties - no framework. The whole interface is a
   few hundred lines; a framework would add more weight than it saved, and
   every rule here can be read and changed without learning one.
   ========================================================================== */

:root {
  --navy:        #0E2A47;
  --navy-2:      #16375C;
  --navy-3:      #1F4875;
  --gold:        #C8A23C;
  --gold-soft:   #F4EBD2;
  --ink:         #1B2430;
  --muted:       #5E6A79;
  --line:        #D8DEE7;
  --bg:          #F4F6F9;
  --panel:       #FFFFFF;
  --green:       #1E7A4B;
  --green-soft:  #E8F4EE;
  --red:         #A8321E;
  --red-soft:    #FBECE8;
  --amber:       #B5791E;
  --amber-soft:  #FBF2E4;
  --radius:      10px;
  --shadow:      0 1px 2px rgba(14,42,71,.06), 0 4px 16px rgba(14,42,71,.06);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
}

/* ---------- layout ---------- */
.app { display: flex; min-height: 100vh; }

.sidebar {
  width: 272px; flex: 0 0 272px;
  color: #C9D4E2;
  display: flex; flex-direction: column;
  /* Sticky and viewport-tall, so the sidebar - and the name/role at the bottom
     of it - stay in view however far the main content is scrolled. */
  position: sticky; top: 0; align-self: flex-start;
  height: 100vh; overflow-y: auto;
  /* Two soft lights over the navy rather than a flat fill. The panel is tall
     and mostly empty, and a flat rectangle of one colour is what made it look
     unfinished. */
  background:
    radial-gradient(420px 260px at 20% 0%, rgba(53,108,168,.55) 0%, rgba(53,108,168,0) 70%),
    radial-gradient(380px 300px at 90% 100%, rgba(200,162,60,.16) 0%, rgba(200,162,60,0) 68%),
    linear-gradient(180deg, var(--navy) 0%, #0A2038 100%);
}
/* A single bright edge where the sidebar meets the page. Cheaper than a
   shadow and it does not darken the content beside it. */
.sidebar::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 1px;
  background: linear-gradient(180deg, rgba(200,162,60,.5), rgba(255,255,255,.06) 45%, rgba(200,162,60,.28));
}
.brand { padding: 20px 20px 16px; border-bottom: 1px solid rgba(255,255,255,.08); }
.brand-logo { display: block; width: 100%; max-width: 186px; height: auto;
              background: #fff; padding: 9px 12px; border-radius: 8px;
              box-shadow: 0 2px 8px rgba(0,0,0,.22); }
.brand .sub  { color: #fff; font-weight: 600; font-size: 14.5px; margin-top: 10px; line-height: 1.3; }

.nav { padding: 12px 10px; flex: 1; }
.nav a {
  display: block; padding: 9px 12px; margin-bottom: 2px;
  color: #C9D4E2; text-decoration: none; border-radius: 7px; font-size: 14px;
}
.nav a:hover { background: rgba(255,255,255,.07); color: #fff; }
.nav a.active { background: var(--gold); color: var(--navy); font-weight: 600; }
.nav .group { padding: 14px 12px 6px; font-size: 10.5px; letter-spacing: .12em;
              text-transform: uppercase; color: #7E93AC; }

.whoami { padding: 14px 18px; border-top: 1px solid rgba(255,255,255,.08); font-size: 12.5px; }
.whoami .n { color: #fff; font-weight: 600; }
.whoami .r { color: var(--gold); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.whoami button {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 12px; padding: 10px 14px;
  background: rgba(200,162,60,.14); border: 1px solid rgba(200,162,60,.45);
  color: #F0DCA0; border-radius: 9px;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: background .16s ease, border-color .16s ease, color .16s ease;
}
.whoami button svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2;
                     fill: none; stroke-linecap: round; stroke-linejoin: round; }
.whoami button:hover { background: var(--gold); border-color: var(--gold); color: #24200C; }

.main { flex: 1; min-width: 0; padding: 26px 30px 60px; }
.page-head { margin-bottom: 20px; }
.page-head h1 { margin: 0 0 4px; font-size: 22px; color: var(--navy); }
.page-head p  { margin: 0; color: var(--muted); font-size: 13.5px; }

/* ---------- panels ---------- */
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 18px;
}
.panel-head {
  padding: 14px 18px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.panel-head h2 { margin: 0; font-size: 15px; color: var(--navy); }
.panel-head .spacer { flex: 1; }
.panel-body { padding: 18px; }
.panel-body.tight { padding: 0; }

/* ---------- stats ---------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 18px; }
.stat { display: block; text-decoration: none; position: relative; overflow: hidden;
        background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
        padding: 15px 16px 13px; box-shadow: var(--shadow);
        transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
/* A wash of navy from the top-left corner, so the tiles are not four identical
   white rectangles. */
.stat::before { content: ""; position: absolute; inset: 0;
                background: radial-gradient(240px 120px at 0% 0%, rgba(31,72,117,.07), rgba(31,72,117,0) 70%);
                pointer-events: none; }
.stat:hover { transform: translateY(-2px); border-color: var(--navy-3);
              box-shadow: 0 2px 4px rgba(14,42,71,.06), 0 14px 30px rgba(14,42,71,.16); }
.stat .go { display: flex; align-items: center; gap: 4px; margin-top: 9px;
            font-size: 11.5px; font-weight: 600; color: var(--navy-3);
            opacity: .75; transition: opacity .16s ease, gap .16s ease; }
.stat:hover .go { opacity: 1; gap: 7px; }
.stat .go svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 2.4;
                fill: none; stroke-linecap: round; stroke-linejoin: round; }
.stat .v { font-size: 26px; font-weight: 700; color: var(--navy); line-height: 1.1; }
.stat .l { font-size: 12px; color: var(--muted); margin-top: 4px; }

/* ---------- alerts ---------- */
.alert { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px;
         border-radius: 8px; margin-bottom: 10px; font-size: 13.5px; }
.alert:last-child { margin-bottom: 0; }
.alert .tag { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; padding: 3px 7px;
              border-radius: 4px; flex: 0 0 auto; }
.alert.error   { background: var(--red-soft); color: var(--ink); }
.alert.error .tag   { background: var(--red); color: #fff; }
.alert.warning { background: var(--amber-soft); color: var(--ink); }
.alert.warning .tag { background: var(--amber); color: #fff; }
.alert.ok { background: var(--green-soft); color: var(--ink); }
.alert.ok .tag { background: var(--green); color: #fff; }

/* ---------- tables ---------- */
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th { text-align: left; padding: 10px 14px; background: #F7F9FC; color: var(--navy);
     font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
     border-bottom: 1px solid var(--line); white-space: nowrap; }
td { padding: 11px 14px; border-bottom: 1px solid #EDF1F6; vertical-align: top; }
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #FAFCFE; }
td.actions { white-space: nowrap; text-align: right; }

/* ---------- badges ---------- */
.badge { display: inline-block; font-size: 11px; font-weight: 600; padding: 2px 8px;
         border-radius: 999px; letter-spacing: .02em; }
.badge.active   { background: var(--green-soft); color: var(--green); }
.badge.inactive { background: #EEF1F5; color: var(--muted); }
.badge.removed  { background: var(--red-soft); color: var(--red); }
.badge.admin    { background: var(--navy); color: #fff; }
.badge.new      { background: var(--gold); color: var(--navy); }
.badge.gold     { background: var(--gold-soft); color: #7A6112; }

/* ---------- forms and buttons ---------- */
label { display: block; font-size: 12.5px; font-weight: 600; color: var(--navy); margin-bottom: 5px; }
input[type=text], input[type=email], input[type=search], select, textarea, input[type=file] {
  width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: 7px;
  font: inherit; font-size: 14px; background: #fff; color: var(--ink);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--navy-3); outline-offset: -1px; border-color: var(--navy-3); }
.field { margin-bottom: 14px; }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.hint { font-size: 12px; color: var(--muted); margin-top: 4px; }

button, .btn {
  font: inherit; font-size: 13.5px; font-weight: 600; padding: 9px 16px; border-radius: 7px;
  border: 1px solid transparent; cursor: pointer; background: var(--navy); color: #fff;
}
button:hover, .btn:hover { background: var(--navy-2); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.secondary { background: #fff; color: var(--navy); border-color: var(--line); }
button.secondary:hover { background: #F4F7FA; }
button.gold { background: var(--gold); color: var(--navy); }
button.gold:hover { background: #B8932F; }
button.danger { background: var(--red); }
button.danger:hover { background: #8E2A18; }
button.small { padding: 5px 10px; font-size: 12.5px; }

/* ---------- messages ---------- */
.msg { padding: 11px 14px; border-radius: 8px; margin-bottom: 14px; font-size: 13.5px; }
.msg.ok    { background: var(--green-soft); color: #145634; border-left: 3px solid var(--green); }
.msg.err   { background: var(--red-soft);   color: #7A2415; border-left: 3px solid var(--red); }
.msg.info  { background: #EEF3FA;           color: #1B3F6B; border-left: 3px solid var(--navy-3); }
/* Neither an error nor neutral: something could not be checked, and the reader
   needs to know the answer in front of them is incomplete. "Could not read the
   membership of X" has to look different from "nothing to report", or it reads
   as everybody being up to date. */
.msg.warn  { background: var(--amber-soft);  color: #7A5210; border-left: 3px solid var(--amber); }

/* ---------- modal ---------- */
.overlay { position: fixed; inset: 0; background: rgba(14,42,71,.55); display: flex;
           align-items: center; justify-content: center; padding: 20px; z-index: 50; }
.modal { background: #fff; border-radius: 12px; max-width: 620px; width: 100%;
         max-height: 88vh; overflow: auto; box-shadow: 0 20px 60px rgba(0,0,0,.3); }
.modal .head { padding: 18px 22px 14px; border-bottom: 1px solid var(--line); }
.modal .head h3 { margin: 0; font-size: 17px; color: var(--navy); }
.modal .body { padding: 20px 22px; }
.modal .foot { padding: 14px 22px 18px; display: flex; gap: 10px; justify-content: flex-end;
               flex-wrap: wrap; border-top: 1px solid var(--line); }

/* ---------- choice cards (duplicate dialog) ---------- */
.choice { border: 1px solid var(--line); border-radius: 9px; padding: 14px; margin-bottom: 10px; cursor: pointer; }
.choice:hover { border-color: var(--navy-3); background: #FAFCFE; }
.choice.recommended { border-color: var(--gold); background: var(--gold-soft); }
.choice .t { font-weight: 700; color: var(--navy); margin-bottom: 4px; }
.choice .c { font-size: 12.5px; color: var(--muted); }

/* ---------- checkbox lists ---------- */
.checklist { max-height: 340px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.checklist label { display: flex; gap: 10px; align-items: flex-start; padding: 9px 13px;
                   border-bottom: 1px solid #EDF1F6; font-weight: 400; margin: 0; cursor: pointer; }
.checklist label:last-child { border-bottom: none; }
.checklist label:hover { background: #F7FAFD; }
.checklist input { margin-top: 3px; }
.checklist .sub { font-size: 12px; color: var(--muted); }

/* ---------- sign-in ----------
   A two-panel layout: the brand and what the portal is for on the left, the
   sign-in form on the right. On a phone the left panel collapses away entirely
   rather than pushing the form below the fold - somebody signing in on a
   handset wants the form, not the marketing. */
/* While the sign-in screen is showing it owns the whole page, so the page
   background changes with it - otherwise the light application background
   shows below the panel on a tall screen. */
body.signed-out { background: #0A2038; }

/* Column, so the copyright line sits UNDER the panel. In a row it becomes a
   flex item beside the panel and drifts off to one side. */
.signin { min-height: 100vh; display: flex; flex-direction: column;
          align-items: center; justify-content: center;
          background:
            radial-gradient(1100px 620px at 12% -8%, #23548C 0%, rgba(35,84,140,0) 62%),
            radial-gradient(900px 560px at 95% 105%, #1B3E68 0%, rgba(27,62,104,0) 60%),
            linear-gradient(160deg, var(--navy) 0%, #0A2038 100%);
          padding: 24px; }

/* ---------- sign-in decoration ----------
   Line drawings in the space either side of the panel. They are drawn in the
   page rather than loaded, so there is nothing to fetch, nothing to licence and
   nothing that can fail on a restricted network. Deliberately faint: they are
   the wall behind the desk, not something to look at. Nothing here is
   interactive and nothing here is read aloud - the layer is aria-hidden and
   ignores the mouse entirely, so it cannot come between anyone and the form. */
.signin { position: relative; overflow: hidden; }

.signin-decor { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.signin-panel { position: relative; z-index: 1; }

.signin-decor .dec { position: absolute; display: block; }
/* One stroke weight and one palette across all six, so they read as a set
   rather than as six clip-art pieces that happen to share a page. */
.signin-decor .s1 { stroke: rgba(255,255,255,.17); stroke-width: 2.2;
                    stroke-linecap: round; stroke-linejoin: round; }
.signin-decor .s2 { stroke: rgba(200,162,60,.34); stroke-width: 2;
                    stroke-linecap: round; stroke-linejoin: round; }
.signin-decor .f1 { fill: rgba(200,162,60,.30); }

/* Measured out from the centre of the page rather than in from the edges. The
   panel is a fixed 940px wide and centred, so an offset from the centre is a
   fixed distance from the panel's edge - which means these can never drift
   into it as the window narrows. Anchoring to the viewport edge instead would
   have looked fine here and collided on a 1366px laptop. */
.dec-book   { right: calc(50% + 670px); top: 19%;    width: 200px; }
.dec-stack  { right: calc(50% + 640px); bottom: 15%; width: 150px; }
.dec-cap    { right: calc(50% + 785px); bottom: 38%; width: 132px; opacity: .8; }
.dec-cert   { left:  calc(50% + 696px); top: 17%;    width: 150px; }
.dec-lamp   { left:  calc(50% + 658px); bottom: 17%; width: 122px; }
.dec-screen { left:  calc(50% + 769px); bottom: 42%; width: 140px; opacity: .8; }

/* As the window narrows the outer drawings are dropped rather than squeezed,
   and the remaining pair moves in. Better to show two comfortably than six
   crowded. */
@media (max-width: 1599px) {
  /* Written with the parent selector so this beats the display:block on
     ".signin-decor .dec" above - a media query adds no weight of its own. */
  .signin-decor .dec-cap, .signin-decor .dec-stack,
  .signin-decor .dec-screen, .signin-decor .dec-lamp { display: none; }
  .dec-book { right: calc(50% + 500px); top: 24%; width: 160px; }
  .dec-cert { left:  calc(50% + 500px); top: 24%; width: 130px; }
}

/* Below this there is no room at all, and the form must win. */
@media (max-width: 1319px) { .signin-decor { display: none; } }

.signin-panel { display: grid; grid-template-columns: 1.05fr .95fr; align-items: stretch;
                gap: 0; max-width: 940px; width: 100%; border-radius: 16px; overflow: hidden;
                box-shadow: 0 30px 90px rgba(0,0,0,.42); }

.signin-brand { padding: 46px 42px; color: #C9D4E2;
                background: linear-gradient(165deg, rgba(255,255,255,.07), rgba(255,255,255,.02));
                border-right: 1px solid rgba(255,255,255,.08);
                display: flex; flex-direction: column; justify-content: center; }
.signin-banner { width: 100%; max-width: 300px; height: auto; margin-bottom: 26px;
                 display: block; }
.signin-logo { width: 178px; max-width: 66%; height: auto; margin-bottom: 24px;
               background: #fff; padding: 11px 15px; border-radius: 9px; }
.signin-brand h2 { margin: 0 0 10px; color: #fff; font-size: 25px; line-height: 1.22; }
.signin-brand p  { margin: 0 0 22px; font-size: 14.5px; line-height: 1.55; color: #AFC2D8; }
.signin-points { list-style: none; margin: 0; padding: 0; }
.signin-points li { position: relative; padding-left: 26px; margin-bottom: 11px;
                    font-size: 13.8px; color: #C9D4E2; }
.signin-points li::before { content: ""; position: absolute; left: 0; top: 7px;
                            width: 9px; height: 9px; border-radius: 2px; background: var(--gold); }

.signin .card { background: #fff; padding: 46px 42px; display: flex; flex-direction: column;
                justify-content: center; }
.signin .name { color: var(--gold); font-weight: 700; letter-spacing: .16em; font-size: 12px; }
.signin h1 { margin: 8px 0 6px; font-size: 24px; color: var(--navy); }
.signin p  { margin: 0 0 22px; color: var(--muted); font-size: 13.5px; }
.signin button { width: 100%; padding: 12px; font-size: 15px; }

@media (max-width: 820px) {
  /* Stacked, not dropped. The panel carries the picture and the three things
     the portal does - hiding it would take that off the small screens, which
     is where most people meet it first. */
  .signin-panel { grid-template-columns: 1fr; max-width: 460px; }
  .signin-brand { padding: 26px 24px; border-right: 0;
                  border-bottom: 1px solid rgba(255,255,255,.08); }
  .signin-banner { max-width: none; margin-bottom: 18px; }
  .signin-banner > img { height: 132px; }
  .signin .card { padding: 30px 24px; }
}

/* ---------- password reset: a small centred, branded frame ----------
   Reached from the e-mailed link while signed out. It sits on the same dark
   sign-in background, as one centred card carrying the BOLDMAC logo and name
   above the password fields - so it reads as part of the portal, not a bare
   form floating on the left. */
.signin-reset { position: relative; z-index: 1; width: 100%; max-width: 440px;
                border-radius: 16px; overflow: hidden;
                box-shadow: 0 30px 90px rgba(0,0,0,.42); }
.signin-reset .reset-head { background: #fff; padding: 32px 40px 0; text-align: center; }
.signin-reset .reset-head .signin-logo { margin: 0 auto 14px; display: block; }
.signin-reset .reset-head h2 { margin: 0; color: var(--navy); font-size: 18px; }
.signin-reset .card { box-shadow: none; border: 0; border-radius: 0;
                      padding: 20px 40px 40px; }
.signin-reset .card h1 { text-align: center; margin-top: 0; }
@media (max-width: 820px) {
  .signin-reset .reset-head { padding: 26px 24px 0; }
  .signin-reset .card { padding: 16px 24px 30px; }
}

/* ---------- the system a training material relates to ----------
   Shown to the assigned employee only, and only when one was given. */
.system-tag { display: flex; align-items: baseline; gap: 8px; margin: 0 0 10px;
              padding: 7px 10px; background: var(--gold-soft); border-radius: 7px; }
.system-tag .l { font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
                 text-transform: uppercase; color: #8A6D14; }
.system-tag .v { font-size: 13.5px; font-weight: 600; color: var(--navy); }

/* ---------- loading ---------- */
.spinner { padding: 40px; text-align: center; color: var(--muted); }
.spinner::before { content: ""; display: block; width: 26px; height: 26px; margin: 0 auto 12px;
                   border: 3px solid var(--line); border-top-color: var(--navy);
                   border-radius: 50%; animation: trc-spin .8s linear infinite; }
@keyframes trc-spin { to { transform: rotate(360deg); } }

/* A button that is working: keeps its size so the layout does not jump. */
button.working { position: relative; color: transparent; }
button.working::after { content: ""; position: absolute; inset: 0; margin: auto;
                        width: 15px; height: 15px; border: 2px solid rgba(255,255,255,.45);
                        border-top-color: #fff; border-radius: 50%; animation: trc-spin .7s linear infinite; }

/* ---------- policy ---------- */
.policy-text { white-space: pre-wrap; background: #F7F9FC; border: 1px solid var(--line);
               border-radius: 8px; padding: 18px; max-height: 44vh; overflow: auto;
               font-size: 13.5px; line-height: 1.65; }
.accept { display: flex; gap: 11px; align-items: flex-start; margin: 18px 0; font-size: 14px; }

/* ---------- training cards ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 15px; }
.card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
        padding: 17px; box-shadow: var(--shadow); display: flex; flex-direction: column; }
.card.unopened { border-left: 4px solid var(--gold); }
.card h3 { margin: 0 0 6px; font-size: 15.5px; color: var(--navy); }
.card .meta { font-size: 12px; color: var(--muted); margin-bottom: 12px; }
.card .tags { margin-bottom: 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.card button { margin-top: auto; }

/* ---------- viewer ---------- */
.viewer { position: fixed; inset: 0; background: #2A2F36; display: flex; flex-direction: column; z-index: 60; }
.viewer .bar { background: var(--navy); color: #fff; padding: 11px 16px; display: flex;
               align-items: center; gap: 14px; flex-wrap: wrap; }
.viewer .bar .title { font-weight: 600; font-size: 14.5px; flex: 1; min-width: 160px; }
.viewer .bar .note { font-size: 11.5px; color: #A9BED6; }
.viewer .bar button { background: rgba(255,255,255,.14); border-color: transparent; }
.viewer .bar button:hover { background: rgba(255,255,255,.25); }
.viewer .stage { flex: 1; overflow: auto; display: flex; justify-content: center; padding: 16px; }
.viewer object, .viewer iframe { width: 100%; height: 100%; border: 0; background: #fff; }

/* ---------- misc ---------- */
.empty { text-align: center; padding: 46px 20px; color: var(--muted); }
.empty h3 { color: var(--navy); margin: 0 0 6px; }
.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.toolbar input[type=search] { max-width: 280px; }
.toolbar select { max-width: 180px; }
.mono { font-family: Consolas, "Courier New", monospace; font-size: 12px; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.muted { color: var(--muted); }

@media (max-width: 860px) {
  .app { flex-direction: column; }
  .sidebar { width: 100%; flex: none; }
  .nav { display: flex; flex-wrap: wrap; gap: 4px; }
  .nav .group { width: 100%; }
  .main { padding: 18px 16px 50px; }
  .row { grid-template-columns: 1fr; }
}

/* ==========================================================================
   THE HERO - welcome, the tagline, today, and now
   --------------------------------------------------------------------------
   On every signed-in page, so the same things are always in the same place.
   Kept deliberately short: it is a header, and every pixel it takes is a pixel
   the actual page does not get.
   ========================================================================== */
.hero {
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px 22px; flex-wrap: wrap;
  border-radius: 18px; padding: 26px 32px; margin-bottom: 24px;
  color: #fff; min-height: 176px;
  background:
    radial-gradient(520px 300px at 8% -30%, rgba(72,132,198,.65) 0%, rgba(72,132,198,0) 66%),
    radial-gradient(420px 260px at 88% 130%, rgba(200,162,60,.30) 0%, rgba(200,162,60,0) 62%),
    linear-gradient(115deg, #143557 0%, #1E4A7A 45%, #16375C 100%);
  box-shadow: 0 10px 30px rgba(14,42,71,.22);
}

/* ---------- the welcome card ----------
   A panel of its own rather than words floating on the banner. It gives the
   greeting an edge to sit against, and it is what stops the name competing
   with the picture next to it. */
.hero-card {
  flex: 0 1 auto; position: relative; z-index: 2;
  background: rgba(255,255,255,.09);
  border: 1px solid rgba(255,255,255,.18);
  border-left: 3px solid var(--gold);
  border-radius: 14px; padding: 18px 26px 20px;
  box-shadow: 0 8px 26px rgba(0,0,0,.20);
  backdrop-filter: blur(3px);
}

/* THE TYPE IS A SYSTEM STACK, NOT A WEB FONT.
   A web font means a request to a font host on first paint. On a network that
   has already blocked one package registry during this project, a blocked font
   means the greeting arrives late or in a fallback that was never designed
   for - and the greeting is the first thing anybody sees. Segoe UI is on every
   Windows machine in the building and needs no request at all. */
.greet {
  margin: 0; font-size: 30px; line-height: 1.12; font-weight: 300;
  letter-spacing: -.012em;
  font-family: "Segoe UI Variable Display", "Segoe UI Semibold", "Segoe UI",
               -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
}
.greet-word { color: #D6E3F2; font-weight: 300; }
/* The name in gold, and brighter at the top than the bottom - the same trick
   the calendar block uses, so the two read as one piece of work. */
.greet-name {
  font-weight: 700;
  background: linear-gradient(180deg, #F0DCA0 0%, var(--gold) 58%, #A9832A 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--gold);
}

.tagline {
  margin: 13px 0 0; padding-left: 15px; position: relative;
  font-size: 17px; line-height: 1.3; color: #E7D9AE;
  letter-spacing: .015em; font-weight: 600;
}
.tagline::before {
  content: ""; position: absolute; left: 0; top: 4px; bottom: 4px; width: 3px;
  border-radius: 2px; background: var(--gold);
}

/* ---------- the two live chips ---------- */
.hero-live { display: flex; gap: 12px; position: relative; z-index: 2;
             flex: 1 1 0; justify-content: flex-end; }
/* The right column of the hero: the date/clock chips, with Sign out stacked
   below them in the top-right corner. */
.hero-right { display: flex; flex-direction: column; align-items: flex-end; gap: 12px;
              flex: 1 1 0; position: relative; z-index: 2; }
.hero-right .hero-live { flex: 0 0 auto; }
.hero-signout { display: inline-flex; align-items: center; gap: 8px;
                padding: 9px 16px; border-radius: 10px;
                background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.30);
                color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
                transition: background .16s ease, border-color .16s ease, color .16s ease; }
.hero-signout:hover { background: var(--gold); border-color: var(--gold); color: #24200C; }
.hero-signout svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; }
.chip {
  display: flex; align-items: center; gap: 11px;
  background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.16);
  border-radius: 12px; padding: 9px 14px 9px 10px;
  backdrop-filter: blur(2px);
}
.chip-text .l1 { font-size: 14px; font-weight: 700; color: #fff; line-height: 1.2;
                 white-space: nowrap; }
.chip-text .l2 { font-size: 11px; color: #B9CBE0; margin-top: 1px; white-space: nowrap; }

/* ---------- today, as a desk calendar ----------
   A month band above and one block per digit below, so the 9th is a single
   block and the 30th is two. The blocks are drawn with gradients and a shadow
   rather than a photograph: nothing to fetch, nothing to licence, and it stays
   sharp on any screen. */
.blocks { display: flex; flex-direction: column; align-items: center; gap: 3px;
          flex: 0 0 auto; }
.blk-month {
  min-width: 46px; text-align: center;
  background: linear-gradient(180deg, #D8B34E, var(--gold));
  color: #2A2008; font-size: 9.5px; font-weight: 800; letter-spacing: .1em;
  padding: 2.5px 7px 3px; border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0,0,0,.28);
}
.blk-days { display: flex; gap: 3px; }
.cube {
  display: block; width: 21px; line-height: 25px; text-align: center;
  background: linear-gradient(180deg, #FFFFFF, #E4E9F0);
  color: var(--navy); font-size: 17px; font-weight: 800;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0,0,0,.30), inset 0 -2px 0 rgba(14,42,71,.10);
}

/* ---------- now, as a clock with hands that move ---------- */
.clock { width: 48px; height: 53px; flex: 0 0 auto; }
.clock .k-bell { fill: rgba(255,255,255,.80); }
.clock .k-arc  { stroke: rgba(255,255,255,.72); stroke-width: 2.6; fill: none;
                 stroke-linecap: round; }
.clock .k-foot { stroke: rgba(255,255,255,.72); stroke-width: 3; stroke-linecap: round; }
.clock .k-body { fill: var(--gold); stroke: rgba(255,255,255,.45); stroke-width: 1.4; }
.clock .k-face { fill: #FFFFFF; }
.clock .k-ticks { stroke: #8A9AB0; stroke-width: 2; stroke-linecap: round; }
.clock .k-h { stroke: var(--navy); stroke-width: 3.4; stroke-linecap: round; }
.clock .k-m { stroke: var(--navy); stroke-width: 2.6; stroke-linecap: round; }
/* The one red thing on the page, because it is the one thing that moves every
   second and it should be obvious that it is moving. */
.clock .k-s { stroke: #C8232C; stroke-width: 1.5; stroke-linecap: round; }
.clock .k-pin { fill: var(--navy); }

/* ---------- the drawing, in the middle ----------
   A book with pages drifting away from it, inside two slowly turning rings.
   Drawn in the page: nothing to fetch, nothing to licence, and it stays sharp
   on any screen. */
.hero-art { position: relative; flex: 0 0 auto; z-index: 2;
            display: flex; align-items: center; gap: 16px; }
.hero-art .hero-drawing { width: 198px; height: auto; display: block; flex: 0 0 auto; }
.hero-pic { flex: 0 0 auto; width: 206px; }
.hero-pic > img { width: 100%; height: 132px; object-fit: cover;
                  border-radius: 12px; box-shadow: 0 8px 22px rgba(0,0,0,.30); }

/* ---------- the photo-swap rule, used by every picture in the portal ----------
   The <img> is hidden until it has actually loaded and the container is given
   .has-photo; only then does the drawing step aside. An absent file therefore
   shows the drawing, never a broken icon. */
.photo-swap > img { display: none; }
.photo-swap.has-photo > img { display: block; }


.hero-art svg { overflow: visible; }

.hero-art .bk { stroke: rgba(255,255,255,.80); stroke-width: 2.6;
                stroke-linecap: round; stroke-linejoin: round; }
.hero-art .ln { stroke: rgba(212,176,86,.95); stroke-width: 2.3; stroke-linecap: round; }
.hero-art .pg { stroke: rgba(255,255,255,.50); stroke-width: 1.8; fill: rgba(255,255,255,.07); }
.hero-art .trail { stroke: rgba(212,176,86,.55); stroke-width: 1.6; stroke-dasharray: 3 6;
                   stroke-linecap: round; }
.hero-art .o1 { stroke: rgba(255,255,255,.26); stroke-width: 1.8; stroke-dasharray: 6 10; }
.hero-art .o2 { stroke: rgba(212,176,86,.45); stroke-width: 1.5; stroke-dasharray: 3 8; }
.hero-art .sparks circle { fill: rgba(212,176,86,.75); }

/* Slowly, and in opposite directions, so the movement registers without being
   something you have to look away from. */
.hero-art .o1     { transform-origin: 140px 75px; animation: hero-spin 30s linear infinite; }
.hero-art .o2     { transform-origin: 140px 75px; animation: hero-spin-back 22s linear infinite; }
.hero-art .sparks { transform-origin: 140px 75px; animation: hero-spin 44s linear infinite; }
.hero-art .pages  { transform-origin: 140px 75px; animation: hero-drift 7s ease-in-out infinite; }

.hero-art .sparks circle { animation: hero-pulse 4.5s ease-in-out infinite; }
.hero-art .sparks circle:nth-child(2) { animation-delay: 1.2s; }
.hero-art .sparks circle:nth-child(3) { animation-delay: 2.4s; }
.hero-art .sparks circle:nth-child(4) { animation-delay: 3.6s; }

@keyframes hero-spin      { to { transform: rotate(360deg); } }
@keyframes hero-spin-back { to { transform: rotate(-360deg); } }
@keyframes hero-pulse     { 0%, 100% { opacity: .28; } 50% { opacity: 1; } }
@keyframes hero-drift     { 0%, 100% { transform: translateY(0); }
                            50%      { transform: translateY(-5px); } }

/* Anyone who has asked their system not to animate gets a still banner. The
   clock still ticks - that is information, not decoration. */
@media (prefers-reduced-motion: reduce) {
  .hero-art .o1, .hero-art .o2, .hero-art .sparks, .hero-art .pages,
  .hero-art .sparks circle { animation: none; }
}


@media (max-width: 760px) {
  .hero { flex-direction: column; align-items: flex-start; gap: 14px; }
  .hero-live { flex-wrap: wrap; }
}

/* ==========================================================================
   BACK - bottom right, floating
   --------------------------------------------------------------------------
   A step backwards is not the main action on any screen, so it does not get
   the top of the page. Fixed to the corner it is always in the same place,
   and it never pushes a heading down to make room for itself.
   ========================================================================== */
.backbtn {
  position: fixed; right: 26px; bottom: 26px; z-index: 40;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--navy); border: 1px solid var(--navy-3); color: #fff;
  padding: 11px 20px 11px 16px; border-radius: 999px;
  font-size: 14px; font-weight: 600; cursor: pointer;
  box-shadow: 0 6px 16px rgba(14,42,71,.28), 0 14px 38px rgba(14,42,71,.22);
  transition: transform .16s ease, box-shadow .16s ease, background .16s ease;
}
.backbtn:hover { background: var(--navy-2); transform: translateY(-2px);
                 box-shadow: 0 8px 20px rgba(14,42,71,.32), 0 18px 46px rgba(14,42,71,.26); }
.backbtn:active { transform: translateY(0); }
.backbtn svg { width: 17px; height: 17px; stroke: currentColor; stroke-width: 2.4;
               fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* The document viewer covers the page; a floating button on top of it would
   sit over the page being read, and its own Close is right there. */
body:has(.viewer) .backbtn { display: none; }

/* ---------- the sidebar drawing ---------- */
.side-art { padding: 6px 26px 14px; opacity: .5; }
.side-art svg { width: 100%; height: auto; display: block; }
.side-art .a1 { stroke: rgba(255,255,255,.30); stroke-width: 2.4;
                stroke-linecap: round; stroke-linejoin: round; }
.side-art .a2 { stroke: rgba(200,162,60,.55); stroke-width: 2.2; stroke-linecap: round; }
.side-art .a3 { stroke: rgba(200,162,60,.7); stroke-width: 2.2; }

/* ==========================================================================
   MY TRAINING
   --------------------------------------------------------------------------
   One material per row, across the full width. The previous card grid put
   three narrow boxes on a wide screen and left two thirds of it empty, which
   is a poor trade when each row now has a title, a system, a progress ring and
   a time estimate to show.

   EVERY MATERIAL GETS ITS OWN COLOUR, worked out from its id rather than
   stored. Nobody has to choose one when uploading, it never needs migrating,
   and the same document is always the same colour on every screen and for
   every reader - which is the only property that makes a colour useful for
   recognising something.
   ========================================================================== */
.training-list { display: flex; flex-direction: column; gap: 14px; }

.tcard {
  position: relative; display: flex; align-items: center; gap: 22px;
  width: 100%; background: #fff; border: 1px solid var(--line);
  border-radius: 14px; padding: 18px 22px 18px 26px;
  box-shadow: var(--shadow); overflow: hidden;
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
/* The material's colour as a band down the edge, and the faintest wash of it
   across the row - enough to tell two rows apart at a glance, not enough to
   fight the text. */
.tcard::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim));
}
.tcard::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 320px;
  background: linear-gradient(90deg, var(--accent-wash), rgba(255,255,255,0));
  pointer-events: none;
}
.tcard:hover { transform: translateY(-1px); border-color: var(--accent-dim);
               box-shadow: 0 2px 4px rgba(14,42,71,.06), 0 14px 32px var(--accent-glow); }

.tcard .body { flex: 1; min-width: 0; position: relative; z-index: 1; }
.tcard h3 { margin: 0 0 5px; font-size: 17px; color: var(--navy); }
.tcard .desc { font-size: 13px; color: var(--muted); margin-bottom: 9px; }
.tcard .facts { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 12.5px;
                color: var(--muted); }
.tcard .facts b { color: var(--ink); font-weight: 600; }
.tcard .tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }

.tcard .actions { position: relative; z-index: 1; display: flex; flex-direction: column;
                  align-items: stretch; gap: 8px; min-width: 156px; }
.tcard .actions button { width: 100%; }
/* The button carries the material's colour too, so the thing you press matches
   the thing you are pressing it for. */
.tcard .actions .open {
  background: var(--accent); border-color: var(--accent);
  box-shadow: 0 6px 16px var(--accent-glow);
}
.tcard .actions .open:hover { background: var(--accent-dim); border-color: var(--accent-dim); }
.tcard .left-note { font-size: 11.5px; color: var(--muted); text-align: center; }

/* ---------- the progress ring ----------
   A conic gradient rather than an SVG arc: one element, no path maths, and the
   percentage is a single custom property that JavaScript can animate. */
.ring {
  --pct: 0;
  position: relative; flex: 0 0 auto;
  width: 108px; height: 108px; border-radius: 50%;
  background: conic-gradient(var(--accent) calc(var(--pct) * 1%), rgba(14,42,71,.09) 0);
  display: grid; place-items: center;
  box-shadow: 0 0 0 1px rgba(14,42,71,.05), 0 8px 22px var(--accent-glow);
}
/* The hole in the middle. An inset shadow gives it the dished look of the
   reference rather than a flat white disc. */
.ring::before {
  content: ""; position: absolute; inset: 11px; border-radius: 50%;
  background: #fff; box-shadow: inset 0 2px 8px rgba(14,42,71,.13);
}
.ring .pv { position: relative; font-size: 23px; font-weight: 700; line-height: 1;
            color: var(--accent); }
.ring .pv span { font-size: 12px; font-weight: 600; margin-left: 1px; }
.ring .pl { position: relative; font-size: 9.5px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.ring.done { box-shadow: 0 0 0 1px rgba(30,122,75,.18), 0 8px 24px rgba(30,122,75,.28); }

.ring-wrap { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.ring-wrap .rlabel { font-size: 11.5px; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .tcard { transition: none; }
}

@media (max-width: 860px) {
  .tcard { flex-direction: column; align-items: stretch; gap: 16px; }
  .tcard .ring-wrap { align-self: flex-start; }
  .tcard::after { display: none; }
}

/* ==========================================================================
   THE PAGE-AT-A-TIME VIEWER
   ========================================================================== */
.viewer .pager { display: flex; align-items: center; gap: 10px; }
.viewer .pager button { min-width: 92px; }
.viewer .pager button:disabled { opacity: .4; cursor: default; }
.viewer .pager .pos { font-size: 13px; color: #CDDCEE; min-width: 116px; text-align: center; }
.viewer .track { height: 3px; background: rgba(255,255,255,.14); position: relative; }
.viewer .track i { position: absolute; left: 0; top: 0; bottom: 0; display: block;
                   background: var(--gold); transition: width .25s ease; }

/* ==========================================================================
   FOOTER
   --------------------------------------------------------------------------
   On every page, quiet, and out of the way of the content above it. The year
   comes from the clock rather than the markup - a hard-coded year is wrong on
   the first of January and nobody notices for months.
   ========================================================================== */
.footer {
  margin-top: 40px; padding: 16px 0 4px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted); text-align: center;
}
/* The floating Back button sits in the same corner, so the footer is given
   room to stay clear of it on a narrow window. */
@media (max-width: 720px) { .footer { padding-bottom: 60px; } }

.signin-foot {
  margin-top: 18px; text-align: center; font-size: 11.5px; color: #8FA6C0;
}

/* ==========================================================================
   THE BAND - the picture panel at the top of a home screen
   --------------------------------------------------------------------------
   Text on the left, picture on the right. A tall panel rather than a full-
   width strip, because the illustrations are portrait: stretched across the
   whole width they would show a thin slice of themselves and nothing else.
   ========================================================================== */
.band {
  position: relative; overflow: hidden;
  border-radius: 16px; margin-bottom: 22px;
  background: linear-gradient(110deg, #123150 0%, #1C4674 55%, #143557 100%);
  box-shadow: 0 8px 26px rgba(14,42,71,.20);
  display: flex; align-items: stretch; height: 226px;
}
.band-text { flex: 1 1 auto; align-self: center; padding: 26px 34px; max-width: 640px; }
.band-text h2 { margin: 0; font-size: 25px; color: #fff; line-height: 1.16; }
.band-text p  { margin: 9px 0 0; font-size: 14.5px; color: #C6D6E8; }

/* margin-left:auto pins it to the right edge: the text is capped for
   readability, so without this the leftover width lands AFTER the picture and
   leaves a strip of empty panel on the end. */
.band-pic { position: relative; flex: 0 0 auto; margin-left: auto;
            width: 38%; max-width: 440px; min-width: 240px; }
/* Absolutely positioned so the picture fills the band instead of its own
   natural height deciding how tall the band is. */
.band-pic > img { position: absolute; inset: 0; width: 100%; height: 100%;
                  object-fit: cover; }
/* The picture is faded into the panel rather than stopped with a hard edge,
   so the two do not look like two separate things bolted together. */
.band-pic::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(18,49,80,.95) 0%, rgba(18,49,80,.30) 34%, rgba(18,49,80,0) 68%);
}
.band-drawing { position: absolute; inset: 0; width: 100%; height: 100%; }
.band.has-photo .band-drawing { display: none; }
.band-drawing .bo  { stroke: rgba(255,255,255,.20); stroke-width: 1.8; stroke-dasharray: 6 10; }
.band-drawing .bo2 { stroke: rgba(212,176,86,.40); stroke-width: 1.5; stroke-dasharray: 3 8; }
.band-drawing .bbk { stroke: rgba(255,255,255,.72); stroke-width: 2.6;
                     stroke-linecap: round; stroke-linejoin: round; }
.band-drawing .bln { stroke: rgba(212,176,86,.90); stroke-width: 2.3; stroke-linecap: round; }
.band-drawing .bsp circle { fill: rgba(212,176,86,.65); }
.band-drawing .bo  { transform-origin: 160px 130px; animation: hero-spin 34s linear infinite; }
.band-drawing .bo2 { transform-origin: 160px 130px; animation: hero-spin-back 25s linear infinite; }

@media (prefers-reduced-motion: reduce) {
  .band-drawing .bo, .band-drawing .bo2 { animation: none; }
}
@media (max-width: 820px) {
  .band { flex-direction: column; height: auto; }
  .band-pic { width: 100%; max-width: none; height: 170px; margin-left: 0; }
  .band-pic::after { background: linear-gradient(180deg, rgba(18,49,80,.85) 0%, rgba(18,49,80,0) 55%); }
}

/* ---------- the empty state, with a picture ---------- */
.empty-pic > img { width: 100%; max-width: 300px; height: auto; margin: 0 auto 18px;
                   border-radius: 12px; box-shadow: var(--shadow); }

/* ---------- the sign-in panel picture ---------- */
.signin-banner { position: relative; width: 100%; max-width: 300px; margin-bottom: 26px; }
.signin-banner > img { width: 100%; height: 168px; object-fit: cover;
                       border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,.34); }
.signin-drawing { width: 100%; height: auto; display: block; }
.signin-banner.has-photo .signin-drawing { display: none; }

/* ==========================================================================
   GLOW ON THE PICTURES
   --------------------------------------------------------------------------
   A ring of light behind each image so it sits ON the navy rather than being
   cut out of it. Two shadows doing two jobs: a tight white line that defines
   the edge, and a wide coloured bloom that ties the picture to the panel it
   is on. Built from box-shadow rather than a filter, because a filter on a
   large image is repainted on every frame of anything animating nearby.
   ========================================================================== */
.hero-pic > img {
  box-shadow:
    0 0 0 1px rgba(255,255,255,.22),
    0 10px 26px rgba(0,0,0,.34),
    0 0 34px rgba(120,180,255,.34),
    0 0 64px rgba(200,162,60,.22);
}
/* Slow, and shallow. The picture is beside a greeting somebody is trying to
   read, so the glow breathes rather than flashes. */
.hero-pic { animation: pic-glow 6s ease-in-out infinite; border-radius: 12px; }
@keyframes pic-glow {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.06); }
}

.band-pic::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  box-shadow: inset 0 0 60px rgba(120,180,255,.28), inset 0 0 120px rgba(200,162,60,.14);
}

.signin-banner > img {
  box-shadow:
    0 0 0 1px rgba(255,255,255,.20),
    0 10px 28px rgba(0,0,0,.40),
    0 0 38px rgba(120,180,255,.30),
    0 0 70px rgba(200,162,60,.20);
}

.empty-pic > img {
  box-shadow:
    0 0 0 1px rgba(14,42,71,.10),
    0 8px 22px rgba(14,42,71,.14),
    0 0 40px rgba(31,72,117,.16);
}

@media (prefers-reduced-motion: reduce) {
  .hero-pic { animation: none; }
}

/* ---------- the sign-in box, larger ----------
   The label above it has gone, so the box itself has to carry more weight.
   16px is also the size below which iOS Safari zooms the page on focus. */
.signin input.big {
  font-size: 16px; padding: 15px 17px; border-radius: 10px;
  border-width: 1.5px;
}
.signin .field { margin-bottom: 20px; }
.signin button { padding: 14px; font-size: 15.5px; }

/* The training cards push their button to the bottom with margin-top:auto so
   that a row of cards lines its buttons up. The sign-in panel is also a .card
   and was inheriting it, which stranded Sign in at the foot of a tall panel
   once the label and the note above it were removed. */
.signin .card button { margin-top: 0; }

/* ==========================================================================
   ANY SCREEN
   --------------------------------------------------------------------------
   Checked at 360, 390, 430, 600, 768, 820, 1024, 1366 and 1920 pixels wide.

   THE RULE: NOTHING IS HIDDEN. Every screen shows the same content; what
   changes is how it is arranged. An earlier version of this section dropped
   the pictures, the navigation headings and the whole sign-in panel on small
   screens - which is how a phone user ends up with a different, poorer
   product than the person on a desktop.

   Nothing here relies on JavaScript, so the layout is right on the first
   paint rather than after a script has measured the window.
   ========================================================================== */

/* Tables carry more columns than a narrow screen has room for. They scroll
   sideways inside their own panel - every column still reachable - rather
   than squeezing to nothing or pushing the page wider than the window. */
.panel-body { overflow-x: auto; }
.panel-body table { min-width: 620px; }

/* ---------- below 1180px: the hero wraps ----------
   The pictures and the clock drop to a second row inside the banner instead
   of being dropped from the page. */
@media (max-width: 1180px) {
  .hero { justify-content: flex-start; }
  .hero-card { flex: 1 1 100%; }
  .hero-art { flex: 0 1 auto; }
  .hero-live { flex: 1 1 auto; justify-content: flex-end; }
}

/* ---------- below 900px: the sidebar becomes a header ----------
   A column layout rather than a drawer behind a button. There are only six
   destinations; hiding them behind a tap to save 60 pixels is a poor trade,
   and a drawer is one more thing that can be left open over the content. */
@media (max-width: 900px) {
  .app { flex-direction: column; }

  .sidebar { width: 100%; flex: 0 0 auto; }
  .sidebar::after { display: none; }          /* the right-hand edge line */

  .brand { display: flex; align-items: center; gap: 14px; padding: 12px 16px; }
  .brand-logo { width: 148px; margin: 0; }
  .brand .sub { margin-top: 0; font-size: 14px; }

  /* The navigation scrolls sideways. The group headings stay, inline, so the
     row still says which links are administration and which are not. */
  .nav { display: flex; align-items: center; gap: 6px; padding: 10px 12px;
         overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .nav .group { padding: 0 8px 0 4px; white-space: nowrap; flex: 0 0 auto; }
  .nav a { white-space: nowrap; margin-bottom: 0; padding: 8px 14px; flex: 0 0 auto; }

  /* Still shown, just small and on the end of the row. */
  .side-art { padding: 0 16px 10px; opacity: .4; }
  .side-art svg { max-width: 150px; }

  .whoami { display: flex; align-items: center; gap: 12px; padding: 10px 16px; }
  .whoami button { width: auto; margin-top: 0; margin-left: auto; padding: 8px 14px; }

  .main { padding: 16px 16px 84px; }

  .hero { flex-direction: column; align-items: stretch; padding: 18px; min-height: 0; }
  .hero-card { padding: 15px 18px 16px; }
  .greet { font-size: 24px; }
  .tagline { font-size: 15.5px; margin-top: 10px; }
  .hero-art { justify-content: center; }
  .hero-live { justify-content: flex-start; flex-wrap: wrap; }
}

/* ---------- phones ---------- */
@media (max-width: 560px) {
  .main { padding: 14px 12px 84px; }
  .page-head h1 { font-size: 19px; }
  .greet { font-size: 21px; }
  .band-text { padding: 20px; }
  .band-text h2 { font-size: 20px; }

  /* The drawing and the photograph share the width rather than one going. */
  .hero-art { gap: 10px; }
  .hero-art .hero-drawing { width: 40%; max-width: 150px; }
  .hero-pic { width: 58%; }
  .hero-pic > img { height: 104px; }

  /* Two chips side by side do not fit; one per line, each full width, keeps
     the date and the time readable instead of clipped. */
  .hero-live { display: grid; grid-template-columns: 1fr; gap: 10px; width: 100%; }
  .chip { width: 100%; }

  /* The stat tiles stop trying to sit two-up at a width where neither fits. */
  .stats { grid-template-columns: 1fr; }

  /* Back stays reachable with a thumb, and clear of the footer. */
  .backbtn { right: 14px; bottom: 14px; padding: 10px 16px 10px 13px; }

  .training-list .tcard { padding: 16px; }
  .tcard .actions { min-width: 0; }

  /* The viewer's controls wrap onto their own lines. The watermark notice
     stays: it is the one line on that screen that tells the reader the
     document carries their name. */
  .viewer .bar { flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
  .viewer .bar .title { flex: 1 0 100%; }
  .viewer .bar .note { flex: 1 0 100%; order: 3; }
  .viewer .pager { flex: 1 1 auto; }
  .viewer .pager button { min-width: 0; flex: 1 1 auto; }

  .signin { padding: 14px; }
}

/* Very narrow, and landscape phones where height is the scarce dimension. */
@media (max-width: 380px) {
  .blk-month { min-width: 40px; }
  .cube { width: 19px; line-height: 23px; font-size: 15px; }
  .hero-art .hero-drawing { max-width: 120px; }
}
@media (max-height: 460px) and (orientation: landscape) {
  .signin { min-height: 0; padding: 20px 14px; }
}

/* ==========================================================================
   THE TRAINING LIST - what is inside one folder
   --------------------------------------------------------------------------
   Rows, not cards. A category may hold twenty documents read in order; twenty
   boxes in a grid is harder to scan than twenty rows, and it buries the one
   thing that matters, which is where you got to.
   ========================================================================== */
.tlist { list-style: none; margin: 0; padding: 0; }

.trow {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 20px; border-bottom: 1px solid var(--line);
  cursor: pointer; transition: background .14s ease;
}
.trow:last-child { border-bottom: 0; }
.trow:hover { background: #F7F9FC; }
/* Keyboard users land here too, and the rows are the only way into a document
   from this screen. */
.trow:focus-visible { outline: 2px solid var(--navy-3); outline-offset: -2px; background: #F7F9FC; }

/* How far through, in the smallest space that still reads. */
.trow-state {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: #EEF2F7; color: var(--muted);
  font-size: 12.5px; font-weight: 700;
}
.trow-state i { font-style: normal; font-size: 9px; font-weight: 600; }
.trow-state.part { background: var(--accent-wash, #EAF1FA); color: var(--navy); }
.trow-state.done { background: var(--green-soft); color: var(--green); }
.trow-state svg { width: 20px; height: 20px; stroke: currentColor; stroke-width: 2.6;
                  fill: none; stroke-linecap: round; stroke-linejoin: round; }

.trow-main { flex: 1; min-width: 0; }
.trow-name { font-size: 15px; font-weight: 600; color: var(--navy); }
.trow-meta { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.trow-go {
  flex: 0 0 auto; display: flex; align-items: center; gap: 5px;
  font-size: 13px; font-weight: 600; color: var(--navy-3);
  opacity: .8; transition: opacity .14s ease, gap .14s ease;
}
.trow:hover .trow-go { opacity: 1; gap: 8px; }
.trow-go svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 2.4;
               fill: none; stroke-linecap: round; stroke-linejoin: round; }

@media (max-width: 560px) {
  .trow { padding: 12px 14px; gap: 12px; }
  .trow-go { font-size: 0; gap: 0; }     /* the arrow alone is enough on a phone */
  .trow-go svg { width: 16px; height: 16px; }
}

/* ---------- the assignment panel ----------
   Three columns side by side so People, Groups and Departments can be seen at
   once. Scrolling within each, because a tenant can have a great many of all
   three and the Review button must stay reachable without scrolling past
   everything else. */
.assign-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px; }
.assign-group h4 { margin: 0 0 8px; font-size: 12px; letter-spacing: .09em;
                   text-transform: uppercase; color: var(--muted); }
.assign-group { max-height: 320px; overflow-y: auto; padding-right: 6px; }
.assign-group label { display: flex; gap: 9px; align-items: flex-start;
                      padding: 7px 8px; border-radius: 7px; cursor: pointer; font-size: 13.5px; }
.assign-group label:hover { background: #F4F7FB; }
.assign-group input { margin-top: 2px; flex: 0 0 auto; }
.assign-group .sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }


/* ==========================================================================
   THE LIBRARY - upload controls
   --------------------------------------------------------------------------
   A bare <input type="file"> is the one control browsers style themselves, and
   left alone it sits in the middle of this interface looking like a different
   website. Only the wrapper and the button are touched; the control itself is
   left functional and keyboard-accessible rather than replaced with a label
   dressed up as a button, which is the usual trick and which breaks for
   anybody not using a mouse.
   ========================================================================== */
input[type="file"] {
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  padding: 9px 10px;
  border: 1px dashed #C9D4E2;
  border-radius: 10px;
  background: #FBFCFE;
  max-width: 100%;
}
input[type="file"]:hover { border-color: var(--gold); background: #FFFDF7; }
input[type="file"]::file-selector-button {
  font: inherit;
  font-size: 13px;
  margin-right: 12px;
  padding: 7px 14px;
  border: 1px solid #D3DCE8;
  border-radius: 8px;
  background: #fff;
  color: var(--navy);
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover { border-color: var(--gold); color: var(--gold-ink, var(--navy)); }

/* The upload row wraps rather than overflowing once the file name is long or
   the screen is narrow - the rule the rest of the interface follows: reflow,
   never hide. */
#lib-files { margin-right: 10px; margin-bottom: 8px; }

/* Per-file results stack under the control, each with its own message. */
#lib-result { margin-top: 12px; }
#lib-result .msg { margin: 6px 0 0; }

/* ==========================================================================
   2 OCTOBER - progress colours, the canvas viewer, the centred hero,
   printing, and the pieces the enterprise specification added
   ========================================================================== */

/* ---------- red / orange / green ----------
   0-30 red, 31-70 orange, 71-100 green. Set as the accent on the element,
   so the ring, the badge and the bar all take the colour from one place. */
.lv-red    { --lv: #C8402F; --lv-soft: #FBE9E6; --lv-glow: rgba(200,64,47,.30); }
.lv-orange { --lv: #D9822B; --lv-soft: #FDF0E2; --lv-glow: rgba(217,130,43,.30); }
.lv-green  { --lv: #1E7A4B; --lv-soft: #E8F4EE; --lv-glow: rgba(30,122,75,.30); }

/* The ring takes the level colour over the per-folder accent. Neon: a soft
   outer glow in the same colour, and a thin bright edge. */
.ring.lv-red, .ring.lv-orange, .ring.lv-green {
  background: conic-gradient(var(--lv) calc(var(--pct) * 1%), rgba(14,42,71,.09) 0);
  box-shadow: 0 0 0 1px rgba(14,42,71,.05), 0 0 0 3px var(--lv-soft), 0 0 22px var(--lv-glow);
}
.ring.lv-red .pv, .ring.lv-orange .pv, .ring.lv-green .pv { color: var(--lv); }

.trow-state.lv-red, .trow-state.lv-orange, .trow-state.lv-green { background: var(--lv-soft); color: var(--lv); }
.trow-state.lv-red.done, .trow-state.lv-orange.done, .trow-state.lv-green.done { background: var(--lv); color: #fff; }

/* A thin bar under the document name, the same colour as the circle. */
.trow-bar { height: 5px; border-radius: 3px; background: #EEF2F7; overflow: hidden; margin: 6px 0 4px; max-width: 320px; }
.trow-bar i { display: block; height: 100%; background: var(--lv); border-radius: 3px;
              box-shadow: 0 0 8px var(--lv-glow); transition: width .5s ease; }
.trow-main .trow-bar { order: 2; }

/* "Assigned system: Training" on the employee's page - read-only, set by an
   administrator under Settings. */
.sys-pill { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 12px;
            background: var(--gold-soft); color: var(--navy); border: 1px solid rgba(200,162,60,.4);
            margin-right: 8px; }
.sys-pill b { font-weight: 700; }

/* ---------- the hero, centred ----------
   The name card and the clock take equal shares; the pictures sit in the
   middle of what is left. Below 1180px the original wrap rules apply. */
@media (min-width: 1181px) {
  .hero-card { flex: 1 1 0; }
  .hero-live { flex: 1 1 0; justify-content: flex-end; }
  .hero-art  { flex: 0 0 auto; justify-content: center; }
}
@media (max-width: 1180px) {
  .hero-art { flex: 1 1 auto; justify-content: center; }
}

/* ---------- the canvas viewer ----------
   The page is a drawing. Nothing on it can be selected, dragged or copied,
   and the right-click menu is suppressed in the script. */
.viewer.canvas .stage { align-items: flex-start; }
.viewer .sheet { position: relative; background: #fff; box-shadow: 0 12px 40px rgba(0,0,0,.45);
                 border-radius: 2px; margin: 0 auto; }
.viewer .sheet canvas { display: block; }
.viewer .sheet-wait { position: absolute; inset: 0; display: grid; place-items: center;
                      background: rgba(255,255,255,.85); color: var(--muted); font-size: 14px; }
.viewer, .viewer * { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.viewer canvas { pointer-events: none; }

/* ---------- printing ----------
   While a document is open, the printed page is blank except for one line.
   A deterrent, as the script comments say: the server only ever sent one
   watermarked page, and this makes even that one not worth printing. */
@media print {
  body.reading * { visibility: hidden !important; }
  body.reading::after {
    content: "Training materials are read online only and cannot be printed.";
    visibility: visible; position: fixed; top: 40%; left: 0; right: 0; text-align: center;
    font: 16px/1.4 Arial, sans-serif; color: #000;
  }
}

/* ---------- folder upload ----------
   A second control beside the file picker: pick a whole folder and every PDF
   in it goes up, with a count of what went in and what did not. */
.upload-row { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.upload-row label.pick { display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
                         padding: 8px 14px; border: 1px dashed var(--navy-3); border-radius: 10px;
                         background: #F7F9FC; font-size: 13.5px; color: var(--navy); }
.upload-row label.pick:hover { background: #EEF3F9; }
.upload-row label.pick input { display: none; }
.upload-row .picked { font-size: 12.5px; color: var(--muted); }
.upload-tally { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.upload-tally span { padding: 4px 10px; border-radius: 999px; font-size: 12px; background: #EEF2F7; color: var(--navy); }
.upload-tally .ok { background: var(--green-soft); color: var(--green); }
.upload-tally .bad { background: #FBE9E6; color: #C8402F; }

/* ---------- PDF cards in a folder ---------- */
.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.doc-card { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; background: #fff;
            display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.doc-card .doc-ic { width: 34px; height: 40px; border-radius: 5px; background: #C8402F; color: #fff;
                    display: grid; place-items: center; font-size: 10px; font-weight: 800; letter-spacing: .05em; }
.doc-card .doc-name { font-weight: 600; font-size: 14px; color: var(--navy); word-break: break-word; }
.doc-card .doc-meta { font-size: 12px; color: var(--muted); }
.doc-card .doc-actions { margin-top: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.doc-card .doc-actions button { padding: 5px 10px; font-size: 12.5px; }

/* ---------- employee summary (dashboard "pick an employee") ---------- */
.emp-pick { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.emp-pick select { min-width: 260px; }
.sum-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-bottom: 14px; }
.sum { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; background: #fff; }
.sum b { display: block; font-size: 22px; color: var(--navy); }
.sum span { font-size: 12px; color: var(--muted); }
.pct-bar { height: 8px; border-radius: 4px; background: #EEF2F7; overflow: hidden; min-width: 90px; }
.pct-bar i { display: block; height: 100%; background: var(--lv, var(--navy-3)); border-radius: 4px; }
.pct-cell { display: flex; align-items: center; gap: 8px; }
.pct-cell small { min-width: 36px; text-align: right; color: var(--muted); }

/* ---------- settings ---------- */
.setting-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.setting-row input { max-width: 320px; }

/* ---------- audit retention ---------- */
.retention { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---------- small screens ---------- */
@media (max-width: 700px) {
  .viewer .bar { flex-wrap: wrap; gap: 8px; }
  .viewer .bar .note { order: 5; width: 100%; }
  .viewer .stage { padding: 8px; }
  .doc-grid { grid-template-columns: 1fr; }
  .sum-row { grid-template-columns: repeat(2, 1fr); }
  .emp-pick select { min-width: 0; width: 100%; }
}

/* ---------- the employee card that opens under the dropdown ---------- */
.emp-card { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; background: #F7F9FC; margin-top: 12px; }
.emp-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.emp-card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.emp-card-actions button { padding: 7px 13px; font-size: 13px; }
.upload-row label.gold-pick { background: var(--gold); color: var(--navy); border: 1px solid var(--gold); font-weight: 600; }
.upload-row label.gold-pick:hover { filter: brightness(1.05); }

/* ---------- folders in the employee overview: a bar each, PDFs on click ---------- */
.folds { display: flex; flex-direction: column; gap: 8px; }
.fold { border: 1px solid var(--line); border-radius: 12px; background: #fff; overflow: hidden; }
.fold-head { display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
             background: #fff; border: 0; padding: 12px 14px; cursor: pointer; font: inherit; color: var(--ink); }
.fold-head:hover { background: #F7F9FC; }
.fold-name { font-weight: 600; color: var(--navy); flex: 1 1 auto; min-width: 0; }
.fold-count { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.fold-head .pct-cell { flex: 0 0 190px; }
.fold-head .pct-bar { flex: 1 1 auto; display: block; }
.fold-chev { width: 18px; height: 18px; stroke: var(--muted); stroke-width: 2.4; fill: none;
             stroke-linecap: round; stroke-linejoin: round; transition: transform .2s; flex: 0 0 auto; }
.fold.open .fold-chev { transform: rotate(90deg); }
.fold-body { border-top: 1px solid var(--line); }
.fold-body table { min-width: 0; }
@media (max-width: 700px) {
  .fold-head { flex-wrap: wrap; }
  .fold-head .pct-cell { flex: 1 1 100%; }
}

/* ---------- SharePoint: the connection line and the picker ---------- */
.sp-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13.5px; }
.sp-bar .btn, .sp-bar button { margin-left: auto; }
.sp-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.sp-dot.on  { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }
.sp-dot.off { background: #C8402F; box-shadow: 0 0 0 3px #FBE9E6; }
.modal.wide { max-width: 820px; }
.sp-crumbs { font-size: 13px; margin-bottom: 8px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 4px; }
.sp-crumbs a { color: var(--navy-3); text-decoration: none; }
.sp-crumbs a:hover { text-decoration: underline; }
.sp-crumbs .cur { color: var(--navy); font-weight: 600; }
.sp-list { border: 1px solid var(--line); border-radius: 10px; max-height: 50vh; overflow: auto; }
.sp-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--line);
          cursor: pointer; font-size: 14px; margin: 0; }
.sp-row:last-child { border-bottom: 0; }
.sp-row:hover { background: #F7F9FC; }
.sp-row.dim { color: var(--muted); cursor: default; }
.sp-row input { margin: 0; flex: 0 0 auto; }
.sp-ic { width: 20px; height: 16px; border-radius: 3px; flex: 0 0 auto; }
.sp-ic.folder { background: var(--gold); border-top-left-radius: 6px; }
.sp-ic.pdf { background: #C8402F; width: 14px; height: 18px; }
.sp-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-meta { font-size: 12px; color: var(--muted); white-space: nowrap; }
.sp-go { font-size: 12.5px; color: var(--navy-3); white-space: nowrap; }
.modal .foot { align-items: center; }

/* ==========================================================================
   5 OCTOBER - the scrolling viewer: scroll, go-to-page, and search
   ========================================================================== */
.viewer.scroll .stage { display: block; align-items: initial; padding: 0; background: #2A2F36; }
.viewer.scroll .scroller { padding: 16px 0 60px; min-height: 100%; }

/* one page */
.viewer .vpage { position: relative; margin: 0 auto 16px; background: #fff;
                 box-shadow: 0 10px 34px rgba(0,0,0,.45); border-radius: 2px; overflow: hidden; }
.viewer .vpage .vph { position: absolute; inset: 0; display: grid; place-items: center;
                      color: #9aa6b2; font-size: 13px; background: #fff; }
.viewer .vpage .vph.err { color: #C8402F; padding: 16px; text-align: center; }
.viewer .vcanvas { display: block; }

/* the highlight overlay - drawn boxes, never selectable text */
.viewer .vhl { position: absolute; top: 0; left: 0; pointer-events: none; }
.viewer .vmark { position: absolute; background: rgba(255,214,0,.42);
                 outline: 1px solid rgba(214,160,0,.8); border-radius: 2px; }

/* the toolbar in the bar */
.viewer .vtools { display: flex; align-items: center; gap: 16px; flex: 1; flex-wrap: wrap; }
.viewer .vtools .goto { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #CDDCEE; white-space: nowrap; }
.viewer .vtools .goto input { width: 52px; text-align: center; padding: 4px 6px; border-radius: 6px;
                              border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.12); color: #fff; font-size: 13px; }
.viewer .vtools .goto b { color: #fff; }
.viewer .vsearch { display: flex; align-items: center; gap: 6px; }
.viewer .vsearch input { width: 230px; max-width: 42vw; padding: 5px 10px; border-radius: 8px;
                         border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.12); color: #fff; font-size: 13px; }
.viewer .vsearch input::placeholder { color: #A9BED6; }
.viewer .vsearch .vcount { font-size: 12px; color: #A9BED6; min-width: 72px; }
.viewer .vsearch button { min-width: 34px; padding: 4px 8px; background: rgba(255,255,255,.14);
                          border: 1px solid transparent; color: #fff; border-radius: 6px; cursor: pointer; }
.viewer .vsearch button:hover:not(:disabled) { background: rgba(255,255,255,.26); }
.viewer .vsearch button:disabled { opacity: .4; cursor: default; }

@media (max-width: 760px) {
  .viewer .vtools { gap: 8px; }
  .viewer .vsearch input { width: 150px; }
  .viewer .bar .title { display: none; }
}

/* ---------- viewer bookmarks ---------- */
.viewer .vbm { position: relative; display: flex; align-items: center; gap: 6px; }
.viewer .vbm > button { padding: 5px 10px; font-size: 13px; background: rgba(255,255,255,.14);
                        border: 1px solid transparent; color: #fff; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.viewer .vbm > button:hover { background: rgba(255,255,255,.26); }
.viewer .vbm > button.on { color: #FFD66B; }
.viewer .vbm-panel { position: absolute; top: 110%; right: 0; z-index: 5; width: 220px; max-height: 320px;
                     overflow: auto; background: #fff; color: var(--ink); border-radius: 10px;
                     box-shadow: 0 14px 40px rgba(0,0,0,.4); padding: 6px; }
.viewer .vbm-row { display: flex; align-items: center; justify-content: space-between; gap: 8px;
                   padding: 7px 10px; border-radius: 7px; cursor: pointer; font-size: 13.5px; color: var(--navy); }
.viewer .vbm-row:hover { background: #F0F4F9; }
.viewer .vbm-x { border: 0; background: transparent; color: var(--muted); font-size: 17px; line-height: 1;
                 cursor: pointer; padding: 0 4px; }
.viewer .vbm-x:hover { color: #C8402F; }
.viewer .vbm-empty { padding: 12px; color: var(--muted); font-size: 12.5px; }

/* ==========================================================================
   5 OCTOBER - richer My training: accordion folders, glowing rings,
   3D gradient buttons, animated bars, a unique sign-out
   ========================================================================== */

/* ---------- the folder accordion ---------- */
.faccs { display: flex; flex-direction: column; gap: 16px; }
.facc {
  position: relative; border-radius: 18px; background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 2px 4px rgba(14,42,71,.05), 0 14px 30px rgba(14,42,71,.07);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  overflow: hidden;
}
.facc::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim));
}
.facc:hover { transform: translateY(-3px); box-shadow: 0 6px 12px rgba(14,42,71,.08), 0 22px 46px var(--accent-glow); border-color: var(--accent-dim); }
.facc.open { box-shadow: 0 8px 16px rgba(14,42,71,.10), 0 26px 54px var(--accent-glow); }

.facc-head { display: flex; align-items: center; gap: 22px; padding: 22px 24px; cursor: pointer; }
.facc-head:focus-visible { outline: 2px solid var(--navy-3); outline-offset: -3px; }
.facc-main { flex: 1 1 auto; min-width: 0; position: relative; z-index: 1; }
.facc-main h3 { margin: 2px 0 6px; font-size: 19px; color: var(--navy); letter-spacing: -.01em; }
.facc-main .facts { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 13px; color: var(--muted); margin-bottom: 10px; }
.facc-main .facts b { color: var(--ink); font-weight: 700; }
.facc-main .tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }

/* a slim animated progress bar under the folder name */
.facc-track { height: 7px; border-radius: 5px; background: #EEF2F7; overflow: hidden; max-width: 460px; }
.facc-track i { display: block; height: 100%; border-radius: 5px; background: var(--lv, var(--accent));
                box-shadow: 0 0 10px var(--lv-glow, var(--accent-glow)); position: relative; transition: width .6s ease; }
.facc-track i::after, .trow-bar i::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform: translateX(-120%); animation: barshine 2.6s ease-in-out infinite;
}
@keyframes barshine { 0% { transform: translateX(-120%); } 60%,100% { transform: translateX(260%); } }

.facc-cta { flex: 0 0 auto; }
.facc-body { border-top: 1px solid var(--line); background: linear-gradient(180deg, #FAFBFD, #fff); padding: 6px 14px 12px; }
.facc-body .tlist { margin: 0; }

/* chevron turns when open */
.facc .btn3d .chev { width: 18px; height: 18px; margin-left: 8px; transition: transform .2s ease; vertical-align: -3px; }
.facc.open .btn3d .chev { transform: rotate(90deg); }

/* ---------- the 3D gradient action button, a rounded capsule ---------- */
.btn3d {
  display: inline-flex; align-items: center; gap: 2px; cursor: pointer;
  padding: 13px 26px; border: 0; border-radius: 999px;
  font-size: 15px; font-weight: 700; color: #fff; letter-spacing: .01em;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dim) 100%);
  box-shadow: 0 2px 0 rgba(0,0,0,.12), 0 10px 22px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,.28);
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.btn3d:hover { transform: translateY(-2px); filter: brightness(1.06);
               box-shadow: 0 3px 0 rgba(0,0,0,.14), 0 16px 30px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,.3); }
.btn3d:active { transform: translateY(1px); box-shadow: 0 1px 0 rgba(0,0,0,.14), 0 6px 14px var(--accent-glow); }

/* ---------- glowing ring ---------- */
.ring.glow { box-shadow: 0 0 0 1px rgba(14,42,71,.05), 0 0 0 4px var(--lv-soft, rgba(14,42,71,.04)),
             0 0 26px var(--lv-glow, var(--accent-glow)); }
.facc-head .ring { width: 118px; height: 118px; }

/* ---------- PDF rows: a little bigger, with animated bars ---------- */
.tlist .trow { padding: 16px 14px; gap: 16px; }
.trow-state { width: 48px; height: 48px; }
.trow-name { font-size: 15.5px; }
.trow-bar { position: relative; overflow: hidden; }

/* ---------- a living band illustration ---------- */
.band .band-drawing .bo  { animation: bandspin 26s linear infinite; transform-origin: 160px 130px; }
.band .band-drawing .bo2 { animation: bandspin 20s linear infinite reverse; transform-origin: 160px 130px; }
.band .band-drawing .bsp circle { animation: bandpulse 4s ease-in-out infinite; }
.band .band-drawing .bsp circle:nth-child(2) { animation-delay: 1s; }
.band .band-drawing .bsp circle:nth-child(3) { animation-delay: 2s; }
.band .band-drawing .bsp circle:nth-child(4) { animation-delay: 3s; }
@keyframes bandspin { to { transform: rotate(360deg); } }
@keyframes bandpulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }

/* ---------- a unique sign-out button, same for all roles ---------- */
.whoami button {
  position: relative; overflow: hidden; border-radius: 12px;
  background: linear-gradient(135deg, rgba(200,162,60,.18), rgba(255,255,255,.04));
  border: 1px solid rgba(212,176,86,.45); color: #F4EBD2; font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 6px 16px rgba(0,0,0,.25);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease, color .15s ease;
}
.whoami button::before {
  content: ""; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.35), transparent);
  transform: skewX(-18deg); transition: left .5s ease;
}
.whoami button:hover {
  transform: translateY(-2px); color: #24200C;
  background: linear-gradient(135deg, var(--gold), #E7C976);
  box-shadow: 0 10px 24px rgba(200,162,60,.4);
}
.whoami button:hover::before { left: 120%; }

/* ---------- subtle motion off for reduced-motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .facc, .btn3d, .whoami button { transition: none; }
  .facc-track i::after, .trow-bar i::after, .band .band-drawing .bo,
  .band .band-drawing .bo2, .band .band-drawing .bsp circle { animation: none; }
}

@media (max-width: 760px) {
  .facc-head { flex-wrap: wrap; gap: 14px; }
  .facc-cta { flex: 1 1 100%; }
  .facc-cta .btn3d { width: 100%; justify-content: center; }
}

/* ---------- the sign-in banner holds a real image, cropped to a tidy card ---------- */
.signin-banner { max-width: 320px; height: auto; }
.signin-banner > img { width: 100%; height: auto; max-height: 260px; object-fit: cover;
                       border-radius: 14px; display: block;
                       box-shadow: 0 12px 30px rgba(0,0,0,.30); }

/* ---------- a picture above the sign-in form (right card) ---------- */
.signin-hero { margin: 0 0 20px; }
.signin-hero > img { width: 100%; max-height: 220px; object-fit: cover; object-position: center 42%;
                     border-radius: 14px; box-shadow: 0 10px 26px rgba(14,42,71,.18); }

/* ---------- viewer zoom bar ---------- */
.viewer .vzoom { display: flex; align-items: center; gap: 7px; }
.viewer .vzoom button { min-width: 30px; padding: 4px 9px; font-size: 15px; line-height: 1;
                        background: rgba(255,255,255,.14); border: 1px solid transparent; color: #fff;
                        border-radius: 6px; cursor: pointer; }
.viewer .vzoom button:hover { background: rgba(255,255,255,.26); }
.viewer .vzoom #v-zfit { font-size: 12.5px; min-width: 38px; }
.viewer .vzoom #v-zlvl { font-size: 12.5px; color: #CDDCEE; min-width: 42px; text-align: center; }
.viewer .vzoom input[type=range] { width: 108px; accent-color: var(--gold); cursor: pointer; }
/* a zoomed page can be wider than the window; let the stage scroll sideways */
.viewer.scroll .stage { overflow: auto; }
.viewer .vpage { max-width: none; }
@media (max-width: 920px) { .viewer .vzoom input[type=range] { width: 70px; } }

/* ---------- a picture in the sidebar's empty middle ---------- */
.sidebar .nav { flex: 0 0 auto; }
.side-photo { flex: 1 1 auto; min-height: 0; display: grid; place-items: center; padding: 14px 18px; overflow: hidden; }
.side-photo > img { width: 100%; max-width: 210px; max-height: 100%; object-fit: cover;
                    border-radius: 14px; box-shadow: 0 12px 30px rgba(0,0,0,.35);
                    border: 1px solid rgba(255,255,255,.12); }
@media (max-width: 900px) { .side-photo { display: none; } }

/* ==========================================================================
   IMPORT RESULT - the box that makes a refused upload impossible to miss
   --------------------------------------------------------------------------
   Shown after an import when anything was refused or was already present. A
   one-line flash is easy to scroll past; this holds the screen until it is
   closed and names every file that did not go in, with the reason beside it.
   ========================================================================== */
.import-report { font-size: 14px; }
.import-report .import-lead { margin: 0 0 12px; font-weight: 600; color: #0E2A47; }
.import-counts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.import-counts .ic { padding: 4px 11px; border-radius: 999px; font-size: 12.5px; font-weight: 600; }
.import-counts .ic.ok  { background: var(--green-soft); color: #145634; }
.import-counts .ic.dup { background: var(--amber-soft); color: #7A5210; }
.import-counts .ic.bad { background: var(--red-soft);   color: #7A2415; }
.import-sec { margin: 0 0 14px; }
.import-sec:last-child { margin-bottom: 0; }
.import-sec h4 { margin: 0 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; }
.import-sec.bad h4 { color: #7A2415; }
.import-sec.dup h4 { color: #7A5210; }
.import-sec.ok  h4 { color: #145634; }
.import-sec ul { list-style: none; margin: 0; padding: 0; }
.import-sec li { display: flex; flex-direction: column; gap: 2px;
                 padding: 8px 11px; border-radius: 8px; margin-bottom: 6px; }
.import-sec li:last-child { margin-bottom: 0; }
.import-sec.bad li { background: var(--red-soft);   border-left: 3px solid var(--red); }
.import-sec.dup li { background: var(--amber-soft); border-left: 3px solid var(--amber); }
.import-sec.ok  li { background: var(--green-soft); border-left: 3px solid var(--green); }
.import-sec li b { font-weight: 600; word-break: break-word; }
.import-sec li span { font-size: 12.5px; opacity: .85; }
