/* ---------------------------------------------------------------------------
   THE LIBRARYONE SIGN-IN PORTAL
   ---------------------------------------------------------------------------
   Ported verbatim from the Self Service MARC Generator's sign-in page
   (its inline <style> plus its static/portal/footer.css), so the two pages are
   the same page. Keep it that way: if the portal changes there, change it here,
   and vice versa — this file exists so the two cannot drift apart silently.

   ONE DEPARTURE FROM THE SOURCE, and it is structural rather than cosmetic:
   every rule that would otherwise match an ordinary element — h1, h2, form,
   .rule, .sub, .eyebrow, .foot, .l1-input — is scoped under .l1-portal. The
   source is a standalone HTML page and can style bare elements safely. This one
   is a route inside a single-page app, where a global `form { margin-top: 22px }`
   or `.l1-input { margin-bottom: 16px }` would quietly reach the Accounts page
   and every other form in the product.

   The .l1-foot* rules are left unscoped, exactly as the source keeps them in
   their own file: the footer is meant to be shared.
   ------------------------------------------------------------------------ */

.l1-portal {
  --ink: var(--l1-ink); --muted: var(--l1-ink-muted); --faint: var(--l1-ink-faint);
  --rule: var(--l1-border); --accent: var(--l1-accent); --raised: var(--l1-raised);
  background: var(--l1-surface);
}

/* The page is two rows: everything, then the footer. */
.l1-portal.page { min-height: 100vh; display: grid; grid-template-rows: 1fr auto; }

/* Same split as the Boundless Intelligence and Boundless Admin sign-in pages:
   the suite panel takes the left, the way in sits on the right at a fixed
   width. The form stays FIRST in the markup and is only placed right, so a
   screen reader and a narrow screen both still meet it before the panel.
   Below 900px the panel drops under the form — it is worth reading, but never
   before the thing the person came to do. */
.l1-portal .two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 460px); min-height: 0; }
.l1-portal .signin { grid-column: 2; grid-row: 1;
          display: flex; align-items: center; justify-content: center; padding: 40px 36px; }
.l1-portal .box { width: 100%; max-width: 352px; }

.l1-portal .marks { display: flex; align-items: center; gap: 12px; }
.l1-portal .marks .l1-logo { height: 26px; margin-left: -.66em; }
.l1-portal .marks .sep { width: 1px; height: 19px; background: var(--rule); flex: none; }
/* Optically matched to the LibraryOne lockup rather than set to the same
   number: the product mark carries more ink above and below its wordmark. */
.l1-portal .b-logo { height: 21px; width: auto; display: block; }
/* This app pairs the LibraryOne lockup with a mark that has no wordmark of its
   own, so the product is named in type beside it. */
.l1-portal .p-name { font-size: 17px; font-weight: 600; letter-spacing: -.01em; color: var(--ink); }

.l1-portal .hair { height: 1px; background: var(--rule); border: 0; margin: 20px 0 18px; }
.l1-portal .rule { height: 2px; width: 60px; background: var(--accent); margin: 0 0 12px; }
.l1-portal .eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .14em;
           text-transform: uppercase; color: var(--muted); }
.l1-portal h1 { font-family: var(--l1-font-display); font-weight: 500; font-size: 44px;
     line-height: 1.05; letter-spacing: -.015em; margin: 4px 0 8px; color: var(--ink); }
.l1-portal .sub { font-size: 14px; color: var(--muted); margin: 0; }

.l1-portal form { margin-top: 22px; }
.l1-portal .l1-input { width: 100%; margin-bottom: 16px; }
.l1-portal form .l1-btn { width: 100%; }
.l1-portal .err { background: #FBE3DE; color: var(--l1-danger); border-radius: var(--l1-radius);
       padding: 10px 12px; font-size: 13px; margin-bottom: 14px; }
.l1-portal .foot { font-size: 12px; color: var(--faint); margin-top: 26px; text-align: center; }

/* The suite, on navy. */
/* Four parts products to one part advertisement: the banner keeps a fifth of
   the column whether or not anything is booked into it, so the products never
   reflow when a campaign starts or ends. */
.l1-portal .suite { grid-column: 1; grid-row: 1;
         background: var(--l1-navy); border-top: 3px solid var(--l1-accent); color: #fff;
         padding: 40px 52px; display: grid; grid-template-rows: 4fr 1fr; gap: 24px;
         min-height: 0; }
.l1-portal .suite-inner { display: flex; flex-direction: column; justify-content: center; min-height: 0; }
/* The slot now holds a booking rather than a placeholder, so the dashed outline
   goes: a dashed box reads as "nothing here yet". */
.l1-portal .adslot { display: flex; align-items: center; gap: 22px; min-height: 0;
          border: 1px solid rgba(255,255,255,.16); border-radius: 4px;
          overflow: hidden; padding: 12px 16px; }
/* The covers run off the edge rather than being counted to fit: the strip is
   wallpaper, and a hard clip would read as a bug. The mask fades the last of
   them out so it reads as "and more" instead. */
.l1-portal .ad-covers { display: flex; align-items: center; gap: 9px;
          flex: 1 1 auto; min-width: 0; overflow: hidden;
          -webkit-mask-image: linear-gradient(90deg, #000 78%, transparent 100%);
                  mask-image: linear-gradient(90deg, #000 78%, transparent 100%); }
.l1-portal .ad-covers img { height: 112px; width: auto; flex: none; display: block;
          border-radius: 2px; box-shadow: 0 5px 14px rgba(0,0,0,.42); }
/* Wide enough that the second line does not orphan its last word; the covers
   take whatever is left, and there are more of them than ever fit anyway. */
.l1-portal .ad-copy { flex: 0 0 auto; max-width: 320px; }
.l1-portal .ad-label { display: block; font-size: 9px; font-weight: 700; letter-spacing: .16em;
          text-transform: uppercase; color: rgba(255,255,255,.38); margin-bottom: 6px; }
.l1-portal .ad-line { display: block; font-size: 14px; font-weight: 700; color: #fff; line-height: 1.3; }
.l1-portal .ad-sub { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.45;
          color: rgba(255,255,255,.7); }
.l1-portal .suite .eyebrow { color: var(--l1-accent); }
/* One line. The size follows the column width rather than being fixed, so the
   sentence still fits when the panel narrows; below 700px a single line would
   be too small to read as a heading, so it wraps again. */
.l1-portal .suite h2 { font-family: var(--l1-font-display); font-weight: 500; color: #fff;
            font-size: clamp(21px, 2.9vw, 40px); line-height: 1.1;
            letter-spacing: -.015em; margin: 12px 0 24px; white-space: nowrap; }
/* Three across: six products in two rows, with hairlines between them. */
.l1-portal .cards { display: grid; grid-template-columns: repeat(3, 1fr);
         gap: 6px; max-width: 820px; }
.l1-portal .pcard { padding: 14px 14px 15px; text-decoration: none; color: inherit; display: block;
         border-radius: 4px; }
.l1-portal .pcard { position: relative; cursor: pointer;
         transition: background-color .14s ease, transform .06s ease; }
.l1-portal .pcard:hover { background: rgba(255,255,255,.09); }
.l1-portal .pcard:focus-within { background: rgba(255,255,255,.07); }
/* Pressed: the whole card takes the press, the way a button would. */
.l1-portal .pcard:active { background: rgba(255,255,255,.14); transform: translateY(1px) scale(.994); }
.l1-portal .pcard:focus-visible { outline: 2px solid var(--l1-accent); outline-offset: -2px; }
/* A card with nowhere to go takes none of a link's affordances: no pointer, no
   hover, no press. That is the closing strip, a product that is not open yet,
   and a product that is open but is not ours to send a customer to. */
.l1-portal .pmore, .l1-portal .pcard--nolink { cursor: default; }
.l1-portal .pmore:active, .l1-portal .pcard--nolink:active { transform: none; background: none; }
.l1-portal .pcard--nolink:hover { background: none; }
@media (prefers-reduced-motion: reduce) {
  .l1-portal .pcard, .l1-portal .pdesc { transition: none; }
  .l1-portal .pcard:active { transform: none; }
}
.l1-portal .prow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* Each mark keeps its own colours, so every one sits on white rather than being recoloured. */
.l1-portal .pchip { display: inline-flex; align-items: center; justify-content: center; background: #fff;
         border-radius: 4px; height: 34px; padding: 0 8px; flex: none; }
.l1-portal .pchip img { max-height: 22px; max-width: 92px; width: auto; display: block; }
.l1-portal .pbadge { font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
          color: rgba(255,255,255,.55); white-space: nowrap; }
/* The card holds two names now — the product, and the successor that is
   coming — so it is a container rather than one big anchor. */
.l1-portal .pname { display: block; font-weight: 700; font-size: 14px; margin-top: 11px;
          color: #fff; text-decoration: none; }
.l1-portal a.pname:hover, .l1-portal a.pname:focus-visible { text-decoration: underline; }
.l1-portal .pname .soon { margin-left: 8px; vertical-align: 2px; }
.l1-portal .ptag { margin-left: 7px; font-size: 9px; font-weight: 700; letter-spacing: .1em;
        text-transform: uppercase; color: rgba(255,255,255,.6);
        border: 1px solid rgba(255,255,255,.3); border-radius: 2px;
        padding: 2px 6px; vertical-align: 2px; }
/* The description is what the card is FOR, but six of them at once is a wall of
   text. It floats out of flow instead, so the cards stay compact rather than
   holding an empty gap, and appears when the card is pointed at or focused
   from the keyboard. */
.l1-portal .pdesc { position: absolute; left: -1px; right: -1px; top: 100%;
         background: #17305A; border: 1px solid rgba(255,255,255,.22);
         box-shadow: 0 14px 30px rgba(0,0,0,.4);
         padding: 11px 14px 12px; font-size: 12.5px; line-height: 1.5;
         color: rgba(255,255,255,.82); z-index: 5;
         opacity: 0; visibility: hidden; transform: translateY(-4px);
         transition: opacity .16s ease, transform .16s ease;
         pointer-events: none; }
.l1-portal .pcard:hover .pdesc, .l1-portal .pcard:focus-within .pdesc {
  opacity: 1; visibility: visible; transform: none; }
/* The hovered card sits above its neighbours so the panel is not clipped by
   the card below it. */
.l1-portal .pcard:hover, .l1-portal .pcard:focus-within { z-index: 6; }
/* The bottom row opens upwards, or the panel would fall out of the grid. */
.l1-portal .pcard.up .pdesc { top: auto; bottom: 100%; transform: translateY(4px); }
.l1-portal .pcard.up:hover .pdesc, .l1-portal .pcard.up:focus-within .pdesc { transform: none; }
/* The successor line. Never a link: these are not open yet, and this page is
   read by external customers, so there is nowhere honest to send them. */
.l1-portal .psub { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
        margin-top: 10px; padding-top: 9px;
        border-top: 1px solid rgba(255,255,255,.12);
        font-size: 11.5px; color: rgba(255,255,255,.72); }
.l1-portal .psub b { font-weight: 700; color: rgba(255,255,255,.9); }
.l1-portal .soon { font-size: 9px; letter-spacing: .08em; text-transform: uppercase;
        color: var(--l1-accent); border: 1px solid rgba(242,140,20,.45);
        border-radius: 2px; padding: 2px 6px; white-space: nowrap; }
/* The last cell is not a product: it closes the grid as a full-width strip, so
   seven items still make a rectangle rather than leaving a hole. */
.l1-portal .pmore { grid-column: 1 / -1; margin-top: 2px;
         border-top: 1px solid rgba(255,255,255,.14);
         display: flex; align-items: center; justify-content: space-between;
         gap: 6px 20px; flex-wrap: wrap; padding: 11px 14px; }
.l1-portal .pmore .pdesc { position: static; opacity: 1; visibility: visible; transform: none;
                background: none; border: 0; box-shadow: none; padding: 0;
                color: rgba(255,255,255,.7); }
.l1-portal .pmore .plink { color: var(--l1-accent); font-weight: 700; font-size: 14px;
                text-decoration: none; white-space: nowrap; }
.l1-portal .pmore .plink:hover, .l1-portal .pmore .plink:focus-visible { text-decoration: underline; }

@media (max-width: 1240px) and (min-width: 901px) {
  .l1-portal .cards { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  .l1-portal .two { grid-template-columns: 1fr; }
  /* Stacked, the placement above would leave a phantom second column. */
  .l1-portal .signin, .l1-portal .suite { grid-column: auto; grid-row: auto; }
  .l1-portal .signin { padding: 36px 22px; }
  /* Stacked, a proportional slot would be a sliver: give it a real height. */
  .l1-portal .suite { padding: 32px 22px; grid-template-rows: auto auto; }
  .l1-portal .suite h2 { white-space: normal; font-size: 30px; }
  /* Stacked, the copy goes above the covers rather than beside them: side by
     side at phone width would leave the strip a sliver. */
  .l1-portal .adslot { min-height: 0; flex-direction: column-reverse; align-items: stretch;
            gap: 12px; padding: 14px; }
  .l1-portal .ad-copy { max-width: none; }
  .l1-portal .ad-covers img { height: 92px; }
  .l1-portal .cards { grid-template-columns: 1fr; }
}


/* ---------------------------------------------------------------------------
   THE LIBRARYONE SITE FOOTER
   Copied from the portal's footer.css, which that app shares between its
   sign-in page and its signed-in pages. Left unscoped for the same reason.
   ------------------------------------------------------------------------ */

.l1-foot {
  background: linear-gradient(100deg, #0B2545 0%, #143B66 48%, #0E2C51 100%);
  color: #fff;
  position: relative;
  overflow: hidden;
}
/* The faint sweep across the band on libraryone.com, drawn rather than shipped
   as an image. */
.l1-foot::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 180% at 78% 10%, rgba(255,255,255,.10), transparent 60%),
    radial-gradient(90% 140% at 96% 96%, rgba(0,181,226,.14), transparent 62%);
  pointer-events: none;
}
.l1-foot-inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px 32px;
  flex-wrap: wrap;
  padding: 18px 32px;
}
.l1-foot-links {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 13px;
  font-weight: 700;
}
.l1-foot-links a { color: #fff; text-decoration: none; }
.l1-foot-links a:hover, .l1-foot-links a:focus-visible { text-decoration: underline; }
.l1-foot-links .bar { color: rgba(255,255,255,.4); }
.l1-foot-legal {
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: rgba(255,255,255,.92);
  display: flex;
  gap: 8px 26px;
  flex-wrap: wrap;
}
.l1-foot-legal a { color: #fff; text-decoration: none; }
.l1-foot-legal a:hover { text-decoration: underline; }

.l1-foot-social { display: flex; align-items: center; gap: 10px; }
.l1-foot-social a {
  display: inline-flex;
  width: 30px; height: 30px;
  border-radius: 6px;
  overflow: hidden;
}
.l1-foot-social a:focus-visible { outline: 2px solid var(--l1-accent, #F28C14); outline-offset: 2px; }
.l1-foot-social svg { width: 100%; height: 100%; display: block; }
.l1-foot-social a:hover { filter: brightness(1.12); }

/* A "Cookies settings" control is a button, not a link: it opens a dialog on
   this page rather than going anywhere. */
.l1-foot-links button {
  font: inherit;
  color: #fff;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.l1-foot-links button:hover { text-decoration: underline; }

@media (max-width: 700px) {
  .l1-foot-inner { padding: 16px 20px; }
  .l1-foot-social { order: 3; }
}
