*{box-sizing:border-box}html,body{margin:0;min-height:100%;font-family:Inter,Segoe UI,Arial,sans-serif;background:#eef4f8}.page{min-height:100vh;overflow:hidden}.topbar{height:118px;padding:22px 6.1vw 18px;background:linear-gradient(90deg,#fbfdff,#f3f8fb);display:flex;justify-content:space-between;align-items:flex-start;position:relative;z-index:20}.brand{color:#0b2e4b;text-decoration:none;font-size:40px;font-weight:700;letter-spacing:-2.8px;display:flex;align-items:center}.brand b{color:#174d75;font-size:43px;font-weight:500;transform:scaleX(.72);margin:-1px -2px 0}.topright{display:flex;flex-direction:column;align-items:flex-end;gap:11px;color:#123b5b}.help{display:flex;align-items:center;gap:8px;color:#163c5c;font-size:13.5px;text-underline-offset:4px}.help i{font-style:normal;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;background:#143f60;color:#fff;font-weight:700;font-size:13px}.strap{margin-top:8px;letter-spacing:3px;font-size:11px;font-weight:600;color:#375c77}.strap em{font-style:normal;margin:0 10px;opacity:.6}.strapline{width:44px;height:3px;border-radius:99px;background:#518ad8}.hero{position:relative;min-height:calc(100vh - 118px);overflow:hidden;background:#082235}.photo{position:absolute;inset:0 0 0 36%;background:url('/static/img/login-bg.jpg') center 49%/cover no-repeat;filter:saturate(.85) contrast(.98) brightness(1.03);z-index:0}.shade{position:absolute;inset:0;z-index:1;background:linear-gradient(90deg,rgba(4,27,44,1) 0%,rgba(4,29,46,.995) 31%,rgba(6,35,53,.93) 44%,rgba(16,52,75,.58) 57%,rgba(225,238,246,.13) 100%)}.ghost{position:absolute;z-index:2;color:rgba(127,179,217,.12);font-size:190px;font-weight:400;transform:scaleX(.72);line-height:1}.ghost.one{left:40.5%;top:4%}.ghost.two{right:1.3%;top:44%}.left{position:relative;z-index:5;width:49%;padding:52px 0 72px 6.1vw}.eyebrow{color:#56aaf2;letter-spacing:2.4px;font-size:12px;font-weight:600;margin-bottom:22px}h1{margin:0;font-size:clamp(38px,3.5vw,62px);line-height:1.04;letter-spacing:-2.6px;font-weight:700;max-width:760px;color:#fff}.client{color:#3b8cd8}.reports{background:linear-gradient(90deg,#b65caf,#d14758);-webkit-background-clip:text;background-clip:text;color:transparent}.lead{max-width:620px;margin:20px 0 0;color:#c9d8e5;font-size:15px;line-height:1.62}.features{max-width:705px;display:grid;grid-template-columns:repeat(4,1fr);gap:25px;margin-top:24px}.features article{color:#fff}.ico{width:54px;height:54px;border-radius:13px;display:grid;place-items:center;background:linear-gradient(145deg,rgba(33,97,142,.72),rgba(19,63,95,.78));border:1px solid rgba(135,200,246,.1)}.ico svg{width:25px;height:25px;fill:none;stroke:#c0e4fd;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}.features h3{margin:8px 0 0;font-size:14px;line-height:1.18}.features p{margin:4px 0 0;color:#bdcfdb;font-size:12px;line-height:1.25}.products{margin-top:25px;width:710px;height:94px;border-radius:12px;background:#fff;box-shadow:0 14px 34px rgba(0,0,0,.17);display:flex;align-items:center;justify-content:space-around;padding:0 34px;color:#222}.prod{display:flex;align-items:center;letter-spacing:-2.8px;font-size:38px;font-weight:600;line-height:1}.prod span{color:#5a5a5c}.prod b{display:inline-block;transform:scaleX(.74);font-weight:500;margin:0 -3px}.prod strong{font-weight:600}.occu b,.occu strong{color:#4a91d2}.exec b,.exec strong{color:#d01535}.products>i{width:1px;height:42px;background:#cdd6de}.phila{display:flex;align-items:center;gap:7px;color:#244d70}.phila>b{font-size:31px;color:#155081}.phila div strong{display:block;font-family:Georgia,serif;font-size:18px;letter-spacing:3px}.phila small{display:block;font-size:6px;letter-spacing:1.4px;color:#7d8b96;margin-top:3px}.login{position:absolute;z-index:8;top:58px;right:10.4vw;width:452px;min-height:0;padding:38px 38px 34px;border-radius:16px;background:rgba(255,255,255,.965);color:#102d47;box-shadow:0 20px 55px rgba(8,35,55,.16);backdrop-filter:blur(7px);border:1px solid rgba(255,255,255,.72)}.login h2{margin:0;font-size:26px;letter-spacing:-.8px}.login>p{margin:15px 0 26px;font-size:14.5px;line-height:1.55;color:#27465f}.login button{width:100%;height:62px;border:0;border-radius:10px;padding:0 18px 0 24px;background:linear-gradient(135deg,#103d5f,#164d73);color:#fff;display:grid;grid-template-columns:auto 1fr auto;gap:15px;align-items:center;font:600 15.5px Inter,Segoe UI,sans-serif;cursor:pointer;box-shadow:0 9px 20px rgba(16,61,95,.16);transition:.18s}.login button:hover{transform:translateY(-1px);filter:brightness(1.04)}.ms{display:grid;grid-template-columns:repeat(2,12px);grid-template-rows:repeat(2,12px);gap:2px}.ms i:nth-child(1){background:#f35325}.ms i:nth-child(2){background:#81bc06}.ms i:nth-child(3){background:#05a6f0}.ms i:nth-child(4){background:#ffba08}.login button>b{font-size:26px;font-weight:300}.access{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:14px;margin:35px 0 27px}.access span{height:1px;background:#cbd8e1}.access em{font-style:normal;font-size:12px;letter-spacing:2.3px;font-weight:600;color:#365d77}.roles,.rolehelp{text-align:center}.roles{font-size:13px;color:#2c4d66}.rolehelp{margin-top:7px;font-size:13px;color:#61798d}.rolehelp a{color:#26465f;font-weight:700;text-underline-offset:3px}.script{position:absolute;z-index:6;right:3.6vw;bottom:58px;color:#1c557f;font-family:Caveat,Segoe Script,cursive;font-size:24px;line-height:1.2;transform:rotate(-5deg);display:flex;flex-direction:column;text-shadow:0 1px 2px rgba(255,255,255,.65)}.script i{width:114px;height:3px;margin:13px 0 0 44px;background:linear-gradient(90deg,#1b82d7,#7e52b4);border-radius:99px}footer{position:absolute;z-index:7;left:6.1vw;bottom:24px;color:rgba(218,231,240,.78);font-size:11px}@media(max-width:1250px){.topbar{padding-left:4vw;padding-right:4vw}.left{width:57%;padding-left:4vw}.login{right:4vw;width:39vw;min-width:430px}.products{width:min(710px,92%)}footer{left:4vw}}@media(max-width:980px){.topbar{height:94px;padding:17px 24px}.brand{font-size:32px}.brand b{font-size:35px}.strap,.strapline{display:none}.hero{min-height:calc(100vh - 94px);padding-bottom:44px}.photo{inset:0;opacity:.56;background-position:62% center}.shade{background:linear-gradient(180deg,rgba(4,27,44,.96),rgba(4,27,44,.88) 54%,rgba(7,32,49,.82))}.left{width:100%;padding:44px 28px 20px}.login{position:relative;inset:auto;width:calc(100% - 56px);min-width:0;margin:10px 28px 30px}.script{display:none}footer{position:relative;left:auto;bottom:auto;margin:0 28px}}@media(max-width:620px){.topbar{height:82px;padding:16px 18px;align-items:center}.brand{font-size:28px}.brand b{font-size:31px}.help span:last-child{display:none}.left{padding:34px 18px 15px}.eyebrow{font-size:11px;letter-spacing:2.3px}h1{font-size:46px;letter-spacing:-3.3px}.lead{font-size:15px}.features{grid-template-columns:1fr 1fr;gap:22px 18px}.products{height:auto;min-height:82px;overflow:auto;justify-content:flex-start;gap:18px;padding:16px 18px}.prod{font-size:30px}.login{width:calc(100% - 36px);margin:10px 18px 28px;padding:34px 24px 32px}.login h2{font-size:29px}.login button{font-size:15px;height:68px}footer{margin:0 18px 20px}}
/* ============================================================================
   Portal additions
   1. Real brand assets in the product strip (replacing the re-drawn wordmarks)
   2. Entrance animations that play on every load/refresh
   Everything here is additive so the supplied design file stays recognisable.
   ========================================================================== */

/* --- 1. product strip: real logos ---------------------------------------- */
.products .prodlogo{height:36px;width:auto;max-width:31%;object-fit:contain;display:block}
/* The Phila mark is square (stacked symbol + wordmark) where the other two are
   wide wordmarks, so it needs more height to read at the same visual weight. */
.products .prodlogo.phila{height:72px}
@media(max-width:620px){
  .products .prodlogo{height:30px}
  .products .prodlogo.phila{height:54px}
}

/* --- 2. entrance animations ---------------------------------------------- */
@keyframes hiRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes hiFade{from{opacity:0}to{opacity:1}}
@keyframes hiCard{from{opacity:0;transform:translateX(46px) scale(.985)}to{opacity:1;transform:none}}
@keyframes hiLine{from{opacity:0;width:0}to{opacity:1;width:44px}}
/* Pop with a slight overshoot so each mark lands rather than just fading. */
@keyframes hiPop{
  0%{opacity:0;transform:scale(.76)}
  62%{opacity:1;transform:scale(1.045)}
  100%{opacity:1;transform:scale(1)}
}
/* The wordmark drops in and casts a soft shadow that settles as it lands. */
@keyframes hiBrand{
  0%{opacity:0;transform:translateY(-16px);filter:drop-shadow(0 20px 28px rgba(8,46,75,.42))}
  70%{opacity:1}
  100%{opacity:1;transform:none;filter:drop-shadow(0 3px 6px rgba(8,46,75,.18))}
}

.anim .reveal{opacity:0}
.anim .r-brand    {animation:hiBrand .95s cubic-bezier(.2,.7,.3,1)  .05s both}
.anim .r-help     {animation:hiFade .6s ease .34s both}
.anim .r-strap    {animation:hiFade .6s ease .40s both}
.anim .r-strapline{animation:hiLine .6s ease .46s both}
.anim .r-eyebrow  {animation:hiRise .7s cubic-bezier(.2,.7,.3,1) .12s both}
.anim .r-h1       {animation:hiRise .85s cubic-bezier(.2,.7,.3,1) .18s both}
.anim .r-lead     {animation:hiRise .8s cubic-bezier(.2,.7,.3,1)  .30s both}
.anim .r-f1       {animation:hiRise .7s cubic-bezier(.2,.7,.3,1)  .38s both}
.anim .r-f2       {animation:hiRise .7s cubic-bezier(.2,.7,.3,1)  .44s both}
.anim .r-f3       {animation:hiRise .7s cubic-bezier(.2,.7,.3,1)  .50s both}
.anim .r-f4       {animation:hiRise .7s cubic-bezier(.2,.7,.3,1)  .56s both}
.anim .r-products {animation:hiRise .75s cubic-bezier(.2,.7,.3,1) .58s both}
/* ...then the three marks pop in one by one inside the settled strip. */
.anim .products .pop{opacity:0}
.anim .products .p1{animation:hiPop .55s cubic-bezier(.2,.8,.3,1) .70s both}
.anim .products .p2{animation:hiPop .55s cubic-bezier(.2,.8,.3,1) .80s both}
.anim .products .p3{animation:hiPop .55s cubic-bezier(.2,.8,.3,1) .90s both}
.anim .r-card     {animation:hiCard .9s cubic-bezier(.2,.7,.3,1)  .24s both}
.anim .r-script   {animation:hiFade .9s ease .92s both}
.anim .r-footer   {animation:hiFade .8s ease .98s both}

/* Motion is decoration here - anyone who has asked the OS to reduce it gets the
   finished page immediately, fully visible, with nothing moving. */
@media (prefers-reduced-motion: reduce){
  .anim .reveal,.anim .products .pop{opacity:1 !important;animation:none !important;filter:none !important;transform:none !important}
  .login button{transition:none}
}

/* --- 3. real Health Impact logo in the topbar ----------------------------
   The header wordmark was drawn in CSS (spans + a scaled ">"). It now uses the
   actual brand asset, so the lockup, weights and the exact navy match every
   other surface. The .brand text rules above still apply to nothing harmful;
   sizing here is by height so the logo scales with the bar at each breakpoint. */
.brand img{height:40px;width:auto;display:block}
@media(max-width:980px){.brand img{height:38px}}
@media(max-width:620px){.brand img{height:32px}}

/* ============================================================================
   4. Fit the whole page in one viewport (no scrolling on the login screen)
   The vertical rhythm is driven by vh so the layout compresses on a short
   window instead of pushing the product strip and footer off the bottom.
   Below 980px the layout stacks (card under the copy), where scrolling is the
   correct behaviour - so the lock only applies to the two-column layout.
   ========================================================================== */
@media (min-width: 981px) {
  html, body { height: 100%; overflow: hidden; }
  .page { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }

  .topbar { height: auto; flex: 0 0 auto; padding: clamp(10px, 1.8vh, 22px) 6.1vw clamp(8px, 1.4vh, 18px); }
  .brand img { height: clamp(26px, 4.4vh, 40px); }
  .hero { flex: 1 1 auto; min-height: 0; overflow: hidden; }

  .left { padding-top: clamp(12px, 3vh, 52px); padding-bottom: clamp(8px, 1.6vh, 24px); }
  .eyebrow { margin-bottom: clamp(8px, 1.6vh, 22px); }
  /* vh in the clamp so the headline shrinks on a short window, not just a narrow one */
  h1 { font-size: clamp(30px, 5.6vh, 62px); }
  .lead { margin-top: clamp(8px, 1.7vh, 20px); font-size: clamp(12.5px, 1.65vh, 15px); }

  .features { margin-top: clamp(10px, 2vh, 24px); }
  .ico { width: clamp(38px, 5.4vh, 54px); height: clamp(38px, 5.4vh, 54px); border-radius: 11px; }
  .ico svg { width: clamp(18px, 2.5vh, 25px); height: clamp(18px, 2.5vh, 25px); }

  .products { margin-top: clamp(10px, 2vh, 25px); height: clamp(62px, 9vh, 94px); }
  .products .prodlogo { height: clamp(24px, 3.6vh, 36px); }
  .products .prodlogo.phila { height: clamp(44px, 6.8vh, 72px); }

  /* The card is absolutely positioned, so cap it against the viewport too. */
  .login { top: clamp(18px, 5vh, 58px); padding: clamp(22px, 3.6vh, 38px) clamp(24px, 2.2vw, 38px) clamp(20px, 3vh, 34px); }
  .login h2 { font-size: clamp(21px, 3.2vh, 26px); }
  .login > p { margin: clamp(9px, 1.6vh, 15px) 0 clamp(14px, 2.6vh, 26px); }
  .login button { height: clamp(50px, 7vh, 62px); }
  .access { margin: clamp(16px, 2.8vh, 35px) 0 clamp(14px, 2.4vh, 27px); }

  footer { bottom: clamp(10px, 1.8vh, 24px); }
  .script { bottom: clamp(28px, 6vh, 58px); font-size: clamp(17px, 2.7vh, 24px); }
}

/* ===========================================================================
 * Hero-first sign-in.
 *
 * The page used to be a pale top bar above a dark hero, with the sign-in card
 * pinned into the hero's right side. Two problems: the bar's near-white
 * gradient met the dark photograph in a hard seam right under a logo that
 * carried its own white plate, and the card - absolutely positioned inside
 * .hero, which is overflow:hidden - was cropped whenever it ran taller than the
 * hero, so it read as cut short.
 *
 * Now the photograph owns the whole viewport, the bar floats on top of it with
 * no background of its own, and signing in is a dialog raised by one button.
 * ==========================================================================*/

/* The bar stops being a band and becomes an overlay. No fill, so there is no
 * seam to see, and the White brand asset sits straight on the picture. */
.topbar {
    position: absolute; inset: 0 0 auto 0;
    height: auto; padding: 26px 6.1vw 0;
    background: none;
    align-items: center;
}
.brand img { height: 42px; width: auto; display: block; }

/* The bar floats on the photograph, and the right-hand end of that photograph is
 * its brightest area - a window. Light type on it had almost no contrast, which
 * is why the help link stopped reading as a link at all. A soft scrim across the
 * top gives the whole bar something to sit on without bringing back the hard
 * seam a solid band created. Behind the content, never over it. */
.topbar::before {
    content: ''; position: absolute; inset: 0 0 -28px 0; z-index: -1;
    background: linear-gradient(180deg, rgba(4, 22, 38, .78), rgba(4, 22, 38, .34) 58%, rgba(4, 22, 38, 0));
    pointer-events: none;
}
.topbar > * { position: relative; }

/* Still a link, and now it looks like one against the picture. */
.help { text-decoration: underline; text-decoration-thickness: 1px; transition: color .15s ease; }
.help:hover { color: #fff; }
.help:hover i { background: rgba(255, 255, 255, .30); }


/* Bar type was navy for a white bar; on the photograph it has to be light. */
.help          { color: rgba(233, 242, 249, .92); }
.help i        { background: rgba(255, 255, 255, .16); color: #fff; }
.strap         { color: rgba(206, 224, 238, .78); }
.strapline     { background: #6aa6e8; }

/* The hero is the page. */
.page  { min-height: 100vh; }
.hero  { min-height: 100vh; }
.left  { padding-top: 124px; }

/* ---- Begin ---------------------------------------------------------------*/
.ctawrap { margin-top: 34px; }

/* Not a button shape. A filled pill sat on top of the hero as a separate object
 * competing with the product strip right above it; as plain type with an arrow
 * it reads as the next thing to do rather than a widget dropped on the page.
 * Still a real <button> - only its skin is gone. */
.cta {
    display: inline-flex; align-items: center; gap: 14px;
    border: 0; background: none; box-shadow: none; padding: 4px 2px;
    cursor: pointer; color: #fff;
    font: 700 25px Inter, Segoe UI, sans-serif; letter-spacing: -.02em;
    transition: color .18s ease;
}
.cta:hover { color: #9fd0ff; }
.cta:focus-visible { outline: 2px solid #6aa6e8; outline-offset: 6px; border-radius: 4px; }

/* Arrow drawn in CSS, so it always matches the label's colour and weight
 * rather than depending on a glyph the font may or may not carry. */
/* The brand mark is a chevron - health |> impact - so the cue beside Begin is
 * the same shape rather than a drawn arrow competing with it. Two borders on a
 * rotated square: no glyph, so it always matches the label's colour and weight. */
.cta .arr {
    width: 13px; height: 13px; flex: 0 0 auto; background: none;
    border-right: 3px solid currentColor; border-top: 3px solid currentColor;
    transform: rotate(45deg);
    transition: transform .2s cubic-bezier(.22,.7,.3,1);
}

/* Borderless still has to say "this does something". A rule under the word - a
 * short stub at rest - runs out to full width on hover or keyboard focus while
 * the chevron moves. Without a cue the label reads as more static copy. */
.cta > span { position: relative; }
.cta > span::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -6px; height: 2px;
    background: currentColor; border-radius: 2px;
    transform: scaleX(.34); transform-origin: left center;
    transition: transform .22s cubic-bezier(.22,.7,.3,1);
}
.cta:hover > span::after,
.cta:focus-visible > span::after { transform: scaleX(1); }
.cta:hover .arr { transform: rotate(45deg) translate(4px, -4px); }

.ctahint { margin-top: 12px; font-size: 12.5px; color: rgba(198, 218, 233, .80); }

/* ---- The sign-in dialog --------------------------------------------------*/
/* [hidden] is only a UA rule of display:none, and ANY display declaration beats
 * it. Setting display:grid here meant the dialog was never actually hidden: its
 * backdrop sat over the whole viewport at z-index 60, transparent and
 * invisible, eating every click on the page - Begin included, and the help link
 * in the bar too. Restore the attribute's meaning explicitly and keep it first,
 * so it can never be lost to a later display rule again. */
.modal[hidden] { display: none !important; }
.modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; }
.modalveil {
    position: absolute; inset: 0; background: rgba(4, 21, 35, .62);
    backdrop-filter: blur(3px);
    opacity: 0; transition: opacity .18s ease;
}
.modal.open .modalveil { opacity: 1; }

/* Reset what .login inherits from its old life pinned inside the hero. */
.modal .login {
    position: relative; inset: auto; top: auto; right: auto;
    margin: 0; width: min(452px, calc(100vw - 36px));
    max-height: calc(100vh - 48px); overflow-y: auto;   /* never cropped again */
    opacity: 0; transform: translateY(14px) scale(.975);
    transition: opacity .19s ease, transform .19s cubic-bezier(.22, .7, .3, 1);
}
.modal.open .login { opacity: 1; transform: none; }

/* Selector must out-rank .login button (0,1,1), which styles every button in
 * the card as a full-width primary. As a plain .modalx (0,1,0) the close
 * control lost and rendered as a 100%-wide navy bar over the heading. */
.login button.modalx {
    position: absolute; top: 12px; right: 14px;
    width: 34px; height: 34px; border: 0; border-radius: 50%;
    background: rgba(16, 45, 71, .07); color: #24506f;
    font: 400 22px/1 Inter, Segoe UI, sans-serif; cursor: pointer;
    transition: background .15s ease;
}
.login button.modalx:hover { background: rgba(16, 45, 71, .14); }

@media (prefers-reduced-motion: reduce) {
    .cta, .modalveil, .modal .login { transition: none; }
}

@media (max-width: 980px) {
    .topbar { position: relative; padding: 18px 24px 0; }
    .left   { padding-top: 26px; }
    .cta    { width: 100%; justify-content: center; }
}

/* Begin joins the entrance sequence, after the product strip. Every .reveal is
 * opacity:0 until its own r-* rule animates it in, so an element given .reveal
 * without a matching rule here never becomes visible at all. */
.r-cta { animation: hiRise .75s cubic-bezier(.2, .7, .3, 1) .66s both; }
