:root {
  --pws-navy: #1B3A5C;
  --pws-steel: #4682B4;
  --pws-red: #E1251B;
  --bg: #F5F7FA;
  --panel: #FFFFFF;
  --ink: #1A1A1A;
  --muted: #6B7280;
  --line: #D8DEE4;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background: var(--bg); color: var(--ink); }
body { min-height: 100vh; display: flex; flex-direction: column; }

/* Sign-in only. The photograph belongs on the arrival screen, where there is
   almost no content to compete with; behind the signed-in workspace it would
   cost legibility on every read and buy nothing after the second visit. The
   class is added by showSignIn() and removed whenever the hub is shown.
   The image is an anonymised PWS photograph — no plant is identifiable, which
   is what makes it safe on every company subdomain. */
body.signin {
  background:
    linear-gradient(rgba(12, 26, 43, 0.74), rgba(12, 26, 43, 0.86)),
    /* The corridor is centred IN THE FILE (cropped 2026-08-03 so its vanishing
       point is the geometric centre). The original photograph had the axis at
       ~55% of width, so `center` centred the file while the coil rows sat
       asymmetrically around the login card. A background-position percentage
       cannot fix that reliably: at a 2:1 viewport `cover` leaves zero
       horizontal overflow, so the percentage has no effect at all. */
    url("/img/bg-coil-corridor-centered.jpg") center / cover no-repeat fixed,
    var(--pws-navy);
}

@media (max-width: 640px) {
  /* iOS ignores background-attachment: fixed and stretches the image badly. */
  body.signin { background-attachment: scroll; }
}

header { background: #000; color: white; padding: 14px 28px; min-height: 168px; display: flex; align-items: center; justify-content: center; gap: 16px; position: relative; box-sizing: border-box; }
header img.cust-logo { height: 116px; max-width: 320px; object-fit: contain; position: absolute; left: 28px; top: 50%; transform: translateY(-50%); }  /* Arconic -- left */
header img.logo { height: 120px; position: absolute; right: 28px; top: 50%; transform: translateY(-50%); }                                            /* PWS -- right */
@media (max-width: 640px) { header { min-height: 108px; } header img.logo { height: 66px; right: 14px; } header img.cust-logo { height: 64px; max-width: 130px; left: 14px; } }
header .title { line-height: 1.1; text-align: center; padding: 0 260px; }
header .title .t1 { display: block; font-family: "Helvetica Neue", "Segoe UI", Arial, sans-serif; font-size: 40px; font-weight: 700; letter-spacing: 0.03em; color: #fff; }
header .title .t2 { display: block; font-family: "Helvetica Neue", "Segoe UI", Arial, sans-serif; font-size: 18px; font-weight: 400; letter-spacing: 0.42em; text-transform: uppercase; color: #aeb8c4; margin-top: 8px; padding-left: 0.42em; }
/* single-line fallback when a hub name has no separator */
header .title:not(:has(.t1)) { font-weight: 700; font-size: 34px; letter-spacing: 0.03em; color: #fff; }
@media (max-width: 640px) { header .title { padding: 0 90px; } header .title .t1 { font-size: 24px; } header .title .t2 { font-size: 13px; letter-spacing: 0.3em; margin-top: 4px; } }

main { flex: 1; display: flex; align-items: center; justify-content: center; padding: 32px 20px; }

.card { width: min(440px, 100%); background: var(--panel); padding: 28px 32px; border-radius: 8px; border: 1px solid var(--line); box-shadow: 0 4px 16px rgba(27,58,92,0.08); }
.card h1 { margin: 0 0 6px; font-size: 28px; color: var(--pws-navy); }
.card p { margin: 0 0 16px; color: var(--muted); font-size: 16px; }

.card input { width: 100%; padding: 11px 13px; font-size: 15px; border: 1px solid var(--line); border-radius: 5px; outline: none; }
.card input:focus { border-color: var(--pws-steel); }
.card button.primary { margin-top: 12px; width: 100%; padding: 11px; background: var(--pws-navy); color: white; border: 0; border-radius: 5px; font-size: 15px; font-weight: 600; cursor: pointer; }
.card button.primary:hover { background: #14304D; }
.card button.primary:disabled { background: #99A8BC; cursor: not-allowed; }

.err { margin-top: 10px; color: var(--pws-red); font-size: 13px; min-height: 18px; }
.help { margin-top: 16px; font-size: 12px; color: var(--muted); }
.help a { color: var(--pws-steel); }

#welcome-link { display: inline-block; margin-top: 14px; padding: 10px 16px; background: var(--pws-navy); color: white; border-radius: 5px; text-decoration: none; font-weight: 600; }
#welcome-link:hover { background: #14304D; }
/* When the card is offering a portal, "sign in with a different account" is the
   FALLBACK, not the action — two navy blocks of equal weight make the reader
   choose between them instead of taking the obvious one. Demoted to a link,
   only in that state, so the ordinary redirect splash keeps its button. */
/* `hidden` only sets display:none in the BROWSER's stylesheet, so any author
   rule beats it and an INLINE style beats it absolutely. #welcome-hubs is
   written as `hidden style="display:grid"`, so it was never actually hidden —
   an empty grid box sat in the card whenever there were no portals to offer.
   Same defect the sign-in overlay in /control/people/ had, by a different
   mechanism. Follows the per-element pattern already used above for
   .card-logo[hidden] and .card-cust[hidden]. */
#welcome-hubs[hidden] { display: none !important; }

#welcome-hubs:not([hidden]) ~ #welcome-link {
  background: none; color: var(--pws-steel); font-weight: 500;
  text-decoration: underline; padding: 6px 0; margin-top: 4px;
}
#welcome-hubs:not([hidden]) ~ #welcome-link:hover { background: none; color: var(--pws-navy); }

footer { padding: 18px 20px; text-align: center; font-size: 12px; color: var(--muted); letter-spacing: 0.04em; }

/* Admin dashboard */
.admin-wrap { width: 100%; max-width: 1000px; }
.admin-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 18px; padding: 0 4px; }
.admin-head h1 { margin: 0; font-size: 22px; color: var(--pws-navy); }
.admin-sub { display: flex; align-items: center; gap: 14px; font-size: 13px; color: var(--muted); }
button.ghost { background: transparent; border: 1px solid var(--line); color: var(--ink); padding: 6px 12px; border-radius: 4px; font: inherit; font-size: 12px; cursor: pointer; }
button.ghost:hover { border-color: var(--pws-navy); color: var(--pws-navy); }

.project-section { margin-bottom: 24px; }
.section-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: var(--muted); margin: 0 4px 8px; }
.project-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.tile { display: block; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 20px 24px; text-decoration: none; color: var(--ink); transition: border-color 120ms ease, transform 120ms ease; }
.tile:hover { border-color: var(--pws-navy); transform: translateY(-1px); }
.tile-name { font-weight: 600; color: var(--pws-navy); font-size: 21px; }
.tile-meta { font-size: 13.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 6px; }
.tile-desc { font-size: 14px; color: #45505e; margin-top: 8px; line-height: 1.45; }
.tile-featured { display: flex; align-items: center; justify-content: space-between; gap: 28px; margin-bottom: 16px; padding: 22px 28px; background: linear-gradient(135deg, #eef4fa, #e2edf6); border: 1px solid var(--pws-steel); }
.tile-featured .tf-main { flex: 1; min-width: 0; }
.tile-featured .tile-name { font-size: 24px; }
.tile-featured .tf-label { display: inline-block; margin-left: 12px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; color: var(--pws-steel); vertical-align: middle; }
.tile-featured .tile-desc { margin-top: 8px; max-width: 660px; font-size: 15px; color: #3f4a57; }
.tile-featured .tf-cta { flex: none; background: var(--pws-navy); color: #fff; padding: 13px 24px; border-radius: 6px; font-weight: 700; font-size: 15px; white-space: nowrap; }
.tile-featured:hover .tf-cta { background: #14304D; }
@media (max-width: 640px) { .tile-featured { flex-direction: column; align-items: flex-start; gap: 14px; } .tile-featured .tf-label { display: block; margin: 4px 0 0; } .tile-featured .tf-cta { width: 100%; text-align: center; box-sizing: border-box; } }
/* --- Accent tile (2026-08-08) ---------------------------------------------
   For the ONE tile in a section that should be opened first — today the Mill 2
   HMI concept on the Chance hub, ahead of the customer's first reveal to their
   technical staff. It has to read as "start here" WITHOUT becoming a second
   featured banner: the featured tile above keeps the full-width gradient and
   the big CTA button, while this stays an ordinary grid cell that is merely
   emphasised. Two full-width banners compete; a banner plus an accented cell
   reads as a clear first and second.

   The left edge is an inset box-shadow rather than a thicker border ON PURPOSE:
   a 4px border would widen the box and knock this cell out of alignment with
   its neighbours in the grid, and box-shadow does not participate in layout. */
.tile-accent { border-color: var(--pws-steel); box-shadow: inset 4px 0 0 var(--pws-steel); background: linear-gradient(135deg, #f4f9fd, #eaf2f9); }
.tile-accent:hover { border-color: var(--pws-navy); box-shadow: inset 4px 0 0 var(--pws-navy); }
/* The qualifier ("interactive preview / your feedback shapes it") carries real
   meaning here — it is what stops a concept being mistaken for the delivered
   system — so it is coloured and weighted rather than left as quiet grey. */
.tile-accent .tile-meta { color: var(--pws-steel); font-weight: 700; }
.tile-accent .ta-cta { display: inline-block; margin-top: 16px; background: var(--pws-navy); color: #fff; padding: 10px 20px; border-radius: 6px; font-weight: 700; font-size: 14px; }
.tile-accent:hover .ta-cta { background: #14304D; }
.tile-url { font-size: 12px; color: var(--muted); margin-top: 8px; font-family: ui-monospace, "SF Mono", Menlo, monospace; overflow-wrap: anywhere; }
.empty { color: var(--muted); padding: 24px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; text-align: center; }

/* Shared section nav — a slim strip directly under <header> on the customer-facing
   pages (project, bliss-helper, m2-helper, clx-review). Rendered/enhanced by
   /js/topnav.js. Scoped to .topnav so it never touches header/page styles.
   NOTE: project/index.html does not load this stylesheet — it carries an in-sync
   copy of these rules inline. Keep the two copies matched. */
.topnav { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; background: #14304D; padding: 0 16px; border-bottom: 1px solid rgba(255,255,255,0.09); }
.topnav a { display: inline-block; color: #c7d3e0; text-decoration: none; font: 600 14px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; padding: 13px 15px; border-bottom: 3px solid transparent; transition: color 120ms ease, border-color 120ms ease; }
.topnav a:hover { color: #fff; }
.topnav a.active { color: #fff; border-bottom-color: var(--pws-steel); }
.topnav a.signout { margin-left: auto; color: #93a5b8; }
.topnav a.signout:hover { color: #fff; }
@media (max-width: 640px) { .topnav { padding: 0 8px; } .topnav a { padding: 12px 11px; font-size: 13px; } }



/* --- Login card branding (2026-08-03) -------------------------------------
   Customer mark above the sign-in field, ProcessWise signature below it. The
   customer's brand leads because the hub belongs to them; the provider signs
   the bottom quietly. Both are constrained by HEIGHT rather than width so that
   marks with very different aspect ratios sit on the same optical baseline. */
.card-logo[hidden] { display: none !important; }   /* see the note on .email-suffix */
.card-logo {
  display: block;
  max-height: 46px;
  max-width: 74%;
  width: auto;
  margin: 2px auto 20px;
  object-fit: contain;
}
/* Full-bleed black bar at the HEAD of the card, carrying the customer's mark.
   Added 2026-08-10: the sign-in card showed only the ProcessWise mark, so a
   customer opening their own portal had nothing confirming they were in the
   right place.
   WHY A BAND RATHER THAN cardLogo: .card-logo places the mark directly on the
   white card, which needs an asset with a transparent background and dark ink.
   Reynolds has one (reynolds-logo-full.png, 67% transparent). Chance's is a
   JPEG with the dark background baked in, and Arconic's PNG is fully opaque —
   both would paint a black rectangle on a white card. A dark band matches the
   asset we actually have, mirrors the .card-provider bar already at the foot,
   and needs no new artwork. If a light-background asset arrives later, set
   cardLogo and this band is skipped automatically. */
.card-cust[hidden] { display: none !important; }
.card-cust {
  margin: -28px -32px 22px;
  padding: 16px 20px;
  background: #000;
  text-align: center;
}
/* Constrained by HEIGHT with a width cap, not by height alone. The customer
   marks differ ~4x in aspect ratio -- chance-logo is a 5.29:1 wordmark,
   arconic-logo is a 1.31:1 near-square badge -- so one max-height rendered
   Arconic at 55px wide against Chance's 222px and it read as broken. Same
   treatment header img.cust-logo already uses: let a tall mark be tall, cap
   the wide one on width. */
.card-cust img { max-height: 68px; max-width: 72%; width: auto; display: inline-block; }

/* Full-bleed black bar at the foot of the card. Negative margins pull it out to
   the card's edges (the card pads 28px/32px), and .card gets overflow:hidden so
   the bar's corners follow the card's radius. */
.card-provider {
  margin: 24px -32px -28px;
  padding: 16px 20px;
  background: #000;
  text-align: center;
}
/* Enlarged 40px -> 56px (2026-08-10). The provider mark sat noticeably smaller
   than the customer mark now above it, which read as an imbalance rather than
   as the quiet signature it is meant to be. It is a wide lockup, so height is
   the right constraint. */
.card-provider img {
  height: 56px;
  width: auto;
  display: inline-block;
}
@media (max-width: 480px) {
  .card-logo { max-height: 40px; margin-bottom: 16px; }
  .card-provider { margin: 20px -20px -22px; }
  .card-cust { margin: -22px -20px 18px; }
  .card-cust img { max-height: 52px; max-width: 76%; }
  .card-provider img { height: 42px; }
}


/* --- Email field with a fixed domain suffix (2026-08-03) -------------------
   The user types only the local part; the hub's domain sits beside it, always
   visible and not deletable. The WRAPPER carries the border so the two read as
   one control. Typing an "@" hides the suffix and hands the full address back,
   so this is a default rather than a lock. */
.email-field { display: flex; align-items: stretch; }
.email-field.has-suffix {
  border: 1px solid var(--line);
  border-radius: 5px;
  background: #fff;
  overflow: hidden;
}
.email-field.has-suffix:focus-within { border-color: var(--pws-steel); }
.email-field.has-suffix input {
  border: 0;
  border-radius: 0;
  width: auto;
  min-width: 0;
  flex: 1 1 auto;
  padding-right: 4px;
}
.email-field.has-suffix input:focus { border: 0; outline: none; }
/* An author `display` declaration BEATS the HTML `hidden` attribute (which the
   UA stylesheet implements as display:none). Without these two rules the suffix
   stayed on screen after the user typed "@", reading as "david@@domain". The
   same trap applies to .card-logo below. */
.email-suffix[hidden],
.email-field:not(.has-suffix) .email-suffix { display: none !important; }
.email-suffix {
  display: flex;
  align-items: center;
  padding: 0 13px 0 2px;
  font-size: 15px;
  color: var(--muted);
  background: #fff;
  white-space: nowrap;
  user-select: none;
}
@media (max-width: 420px) {
  .email-suffix { font-size: 13px; padding: 0 9px 0 2px; }
}


/* --- Sign-in screen: no header band (2026-08-03) ---------------------------
   The arrival screen carries the customer's mark ON THE CARD, so the black
   header band above it was a second, competing lockup. Hiding it also fixes the
   framing: the band is 168px tall, so it pushed the card below the optical
   centre and made the fixed background photograph look off-centre. With the
   band gone, `main` fills the viewport and the card centres properly. The band
   returns the moment the hub renders (showSignIn adds .signin, the hub removes
   it). */
body.signin > header { display: none; }
body.signin > main { min-height: 100vh; padding-top: 24px; padding-bottom: 24px; }
body.signin .card { overflow: hidden; }
