/* Customer portal styles — external so the portal can enforce a strict CSP
   (style-src 'self'), no 'unsafe-inline' needed. */
:root{
  --blue:#2563eb;--blue-dk:#1d4ed8;
  --ink:#0f172a;--muted:#64748b;--line:#e2e8f0;
  --bg:#0b1220;--card:#ffffff;
  --red:#dc2626;--ok:#059669;--warn:#b45309;
  --shadow-lg:0 10px 30px -8px rgba(0,0,0,.35),0 4px 12px -6px rgba(0,0,0,.25);
}
*{box-sizing:border-box}
/* NOTE: do NOT clamp html/body to height:100%. Combined with the flex
   centering below it traps tall pages: the card overflows the top of the
   viewport and the browser cannot scroll up to it (nav becomes unreachable
   on phones). Let the document grow with its content instead. */
html{height:auto}
body{
  margin:0;
  font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  color:var(--ink);
  background:linear-gradient(135deg,#0b1220 0%,#1e293b 55%,#312e81 100%);
  background-attachment:fixed;
  min-height:100vh;
  min-height:100dvh;      /* accounts for mobile browser chrome */
  display:flex;
  justify-content:center;
  align-items:flex-start;  /* centering is done by the card's auto margins */
  padding:1.25rem;
}
.portal-card{
  background:var(--card);
  border-radius:18px;
  box-shadow:var(--shadow-lg);
  width:100%;max-width:400px;
  padding:2rem 1.9rem 2.1rem;
  /* auto margins centre the card when it fits, and degrade to top-aligned
     (fully scrollable) when it is taller than the viewport. */
  margin:auto;
}
.logo{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  margin-bottom:1.4rem;
}
.logo .mark{
  width:76px;height:76px;border-radius:20px;
  display:flex;align-items:center;justify-content:center;
  font-size:2.4rem;
  background:linear-gradient(135deg,var(--blue),#7c3aed);
  color:#fff;box-shadow:0 6px 18px -6px rgba(37,99,235,.6);
  margin-bottom:.7rem;
}
.logo .name{font-size:1.15rem;font-weight:800;letter-spacing:.01em}
.logo .sub{font-size:.82rem;color:var(--muted);margin-top:.15rem}
h1{font-size:1.05rem;margin:0 0 1rem;text-align:center;font-weight:700}
label{display:block;font-size:.82rem;color:var(--muted);margin:.7rem 0 .25rem;font-weight:600}
input{
  width:100%;padding:.65rem .7rem;
  border:1px solid var(--line);border-radius:10px;
  font-size:1rem;font-family:inherit;background:#fff;color:var(--ink);
}
input:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
button{
  width:100%;margin-top:1.1rem;padding:.7rem;
  border:0;border-radius:10px;
  background:var(--blue);color:#fff;font-weight:700;font-size:1rem;
  cursor:pointer;
}
button:hover{background:var(--blue-dk)}
.links{
  margin-top:1.15rem;display:flex;flex-direction:column;gap:.5rem;
  text-align:center;font-size:.9rem;
}
.links a{color:var(--blue);text-decoration:none;font-weight:600}
.links a:hover{text-decoration:underline}
.notice{
  margin:0 0 1rem;padding:.6rem .75rem;border-radius:10px;font-size:.88rem;
  background:rgba(180,83,9,.1);border:1px solid rgba(180,83,9,.3);color:var(--warn);
}
.error{
  margin:0 0 1rem;padding:.6rem .75rem;border-radius:10px;font-size:.88rem;
  background:rgba(220,38,38,.08);border:1px solid rgba(220,38,38,.3);color:var(--red);
}
.foot{margin-top:1.4rem;text-align:center;font-size:.72rem;color:var(--muted)}
/* --- registration form (wider card + grid rows) --- */
.portal-card.wide{max-width:520px}
.section-head{
  margin:1.5rem 0 .2rem;padding-top:1rem;border-top:1px solid var(--line);
  font-size:.95rem;font-weight:800;
}
.hint{
  margin:.5rem 0 .2rem;font-size:.8rem;line-height:1.4;color:var(--warn);
  background:rgba(180,83,9,.08);border:1px solid rgba(180,83,9,.25);
  border-radius:9px;padding:.55rem .7rem;
}
.opt{font-weight:400;text-transform:none;color:var(--muted)}
.lead{margin:0 0 1rem;font-size:.88rem;line-height:1.5;color:var(--muted);text-align:center}
.subhint{margin:.35rem 0 0;font-size:.76rem;line-height:1.4;color:var(--muted)}
.topnav{display:flex;gap:.15rem;flex-wrap:wrap;justify-content:center;
        margin:0 0 .5rem;padding-bottom:.6rem;border-bottom:1px solid var(--line)}
.topnav a{font-size:.8rem;font-weight:600;text-decoration:none;color:var(--fg);
          padding:.35rem .6rem;border-radius:7px}
.topnav a:hover{background:rgba(127,127,127,.12)}
.topnav a.quiet{color:var(--muted);font-weight:500}
.whoami{font-size:.72rem;color:var(--muted);text-align:center;margin-bottom:1rem}
.section-head{font-size:.72rem;font-weight:700;text-transform:uppercase;
              letter-spacing:.08em;color:var(--muted);margin:1.4rem 0 .5rem;
              padding-bottom:.3rem;border-bottom:1px solid var(--line)}
ul.plain{list-style:none;margin:.2rem 0;padding:0;font-size:.86rem;line-height:1.7}
ul.plain li{padding:.3rem 0;border-bottom:1px solid var(--line)}
ul.plain li:last-child{border-bottom:none}
table.mini{width:100%;border-collapse:collapse;font-size:.82rem;margin:.3rem 0}
table.mini th{text-align:left;font-size:.68rem;text-transform:uppercase;
              letter-spacing:.05em;color:var(--muted);font-weight:700;
              padding:.35rem .4rem;border-bottom:1px solid var(--line)}
table.mini td{padding:.45rem .4rem;border-bottom:1px solid var(--line);vertical-align:top}
table.mini tr:last-child td{border-bottom:none}
table.mini td.r,table.mini th.r{text-align:right}
table.mini .small{font-size:.74rem;color:var(--muted)}
table.kv{width:100%;border-collapse:collapse;font-size:.86rem}
table.kv th{text-align:left;width:8.5rem;font-weight:600;color:var(--muted);
            padding:.4rem .4rem .4rem 0;vertical-align:top;font-size:.8rem}
table.kv td{padding:.4rem 0;vertical-align:top}
.body-text{margin:.3rem 0;font-size:.86rem;line-height:1.55;white-space:pre-wrap}
label.check{display:flex;gap:.5rem;align-items:flex-start;margin:.9rem 0 .3rem;
            font-size:.8rem;font-weight:400;text-transform:none;
            letter-spacing:normal;color:var(--fg);line-height:1.45}
label.check input{width:auto;margin:.15rem 0 0}
.planrow{border:1px solid var(--line);border-radius:10px;padding:.75rem .85rem;
         margin-bottom:.6rem}
.planaddr{font-size:.86rem;font-weight:600;margin-bottom:.4rem}
.planline{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.tier{display:inline-block;font-size:.72rem;font-weight:800;letter-spacing:.06em;
      text-transform:uppercase;padding:.22rem .55rem;border-radius:999px;
      border:1px solid var(--line)}
.tier-basic{background:#e5e7eb;color:#374151;border-color:#d1d5db}
.tier-silver{background:#e2e8f0;color:#334155;border-color:#cbd5e1}
.tier-gold{background:#fef3c7;color:#92400e;border-color:#fde68a}
.tier-platinum{background:#ede9fe;color:#5b21b6;border-color:#ddd6fe}
.tier-none{background:transparent;color:var(--muted);font-weight:600}
.planprice{font-size:.86rem;font-weight:700}
.planprice.muted-txt{font-weight:500;color:var(--muted);font-size:.8rem}
.planstatus{font-size:.72rem;color:#b45309;font-weight:600}
.plandesc{font-size:.8rem;line-height:1.45;margin-top:.4rem}
.planmeta{font-size:.73rem;color:var(--muted);margin-top:.35rem}
.row{display:flex;gap:.6rem}
.row .col-6{flex:2 1 0}
.row .col-3{flex:1 1 0}
.check{
  display:flex;align-items:flex-start;gap:.55rem;
  margin:.9rem 0 .2rem;font-size:.85rem;color:var(--ink);font-weight:500;cursor:pointer;
}
.check input{width:auto;margin-top:.15rem;flex:0 0 auto}
.success{
  margin:0 0 1rem;padding:.7rem .8rem;border-radius:10px;font-size:.9rem;line-height:1.45;
  background:rgba(5,150,105,.08);border:1px solid rgba(5,150,105,.3);color:var(--ok);
}
@media(max-width:420px){
  .portal-card{padding:1.6rem 1.25rem 1.7rem;border-radius:14px}
  .logo .mark{width:64px;height:64px;font-size:2rem}
  .row{flex-direction:column;gap:0}
}

/* ---- one-time-code field (was an inline style attribute) ---- */
.codeinput{text-align:center;font-size:1.5rem;letter-spacing:.5rem;font-weight:700}

/* ---- destructive action (cancel a service request) ----
   Outlined rather than solid red: it sits under the request detail, and a
   full-bleed red block reads as an error message rather than a button. */
.btn-danger{
  background:transparent;color:var(--red);
  border:1px solid rgba(220,38,38,.45);
}
.btn-danger:hover{background:rgba(220,38,38,.08)}
/* The shared button rule sets width:100%; keep the destructive action from
   dominating the page on desktop while staying full-width and tappable on a
   phone (min 44px target). */
.cancelform{margin-top:1.1rem}
.cancelform button{margin-top:0;min-height:44px}
@media(min-width:421px){
  .cancelform button{width:auto;min-width:15rem;padding-left:1.2rem;padding-right:1.2rem}
}

/* ---- Phase 6: mobile responsiveness ----
   Targets: no horizontal scroll at 320px, touch targets >= 44px, tables that
   reflow instead of overflowing. */

/* Never let a long word/address force horizontal scroll.
   Only clip on the root element — setting overflow-x on BOTH html and body
   promotes body to a scroll container and can re-break vertical scrolling. */
html{max-width:100%;overflow-x:hidden}
body{max-width:100%}
.planaddr,.planline,ul.plain li,table.mini td,table.kv td{
  overflow-wrap:anywhere;word-break:break-word}

/* Comfortable touch targets everywhere (iOS guideline is 44px). */
button,input[type="submit"],.topnav a{min-height:44px}
button{font-size:1rem}
input,select,textarea{min-height:44px;font-size:1rem}  /* 16px stops iOS zoom-on-focus */

@media (max-width:640px){
  body{padding:.6rem}
  .portal-card,.portal-card.wide{padding:1.15rem 1rem;border-radius:12px;
    max-width:100%;margin:.5rem auto}
  .topnav{gap:.1rem;padding-bottom:.5rem}
  .topnav a{padding:.5rem .5rem;font-size:.82rem;flex:1 1 auto;text-align:center}

  /* Stack the address row instead of squeezing three fields side by side. */
  .row{flex-direction:column;gap:0}
  .row .col-6,.row .col-3{flex:1 1 auto;width:100%}

  /* Hide only columns explicitly marked .hide-sm. Positional nth-child rules
     were wrong here: /requests and /account have different column orders, so
     nth-child(3) hid Status on the dashboard. */
  table.mini th.hide-sm,table.mini td.hide-sm{display:none}

  /* Key/value detail table stacks label above value. */
  table.kv th,table.kv td{display:block;width:100%;padding:.15rem 0}
  table.kv th{color:var(--muted);font-size:.72rem;text-transform:uppercase;
    letter-spacing:.05em;padding-top:.55rem}
  table.kv tr{display:block;border-bottom:1px solid var(--line);padding:.15rem 0}
  table.kv tr:last-child{border-bottom:none}

  .planline{gap:.4rem}
  .codeinput{font-size:1.35rem;letter-spacing:.4rem}
}

@media (max-width:380px){
  .topnav a{font-size:.76rem;padding:.5rem .35rem}
  /* Very narrow: also drop columns marked .hide-xs. */
  table.mini th.hide-xs,table.mini td.hide-xs{display:none}
}

/* Respect reduced-motion and dark-mode preferences. */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
}

/* ---- Phase 6: touch target remediation (found by real-viewport audit) ----
   Text links in .links/.foot rendered ~16px tall and the confirm checkbox 13px.
   Padding gives a >=44px tap area without changing the visual text size. */
.links a{display:inline-block;padding:.7rem .25rem;line-height:1.2;min-height:44px}
.links{margin-top:.35rem}
.foot a{display:inline-block;padding:.6rem .25rem;min-height:44px}

/* Checkbox: enlarge the control itself and make the whole label tappable. */
label.check{min-height:44px;padding:.35rem 0;cursor:pointer;align-items:center}
label.check input[type="checkbox"]{width:24px;height:24px;min-height:24px;
  flex:0 0 24px;margin:0}

/* Links inside data tables (job numbers) get a real tap area. */
table.mini td a{display:inline-block;padding:.6rem .2rem;min-height:44px;
  line-height:1.4}

/* Keep the auth-page helper links comfortable too. */
.altlinks a,.subhint a{display:inline-block;padding:.5rem .2rem;min-height:44px}

/* ---- Phase 8: customer service requests ---- */
/* Primary action link styled as a button (an <a>, so it needs the button look
   applied explicitly rather than inheriting from the button element rules). */
.btn-primary{
  display:inline-block;width:auto;
  background:var(--blue);color:#fff;
  font-weight:700;font-size:.95rem;text-decoration:none;
  padding:.7rem 1.2rem;border-radius:10px;
  min-height:44px;line-height:1.6;
  text-align:center;
}
.btn-primary:hover{background:var(--blue-dk);text-decoration:none}
@media (max-width:640px){
  /* Full-width tap target on phones. */
  .btn-primary{display:block;width:100%}
}
/* The request form's selects need the same treatment as inputs — without this
   they render at the browser default size and break the 44px tap target rule. */
select{
  width:100%;padding:.65rem .7rem;
  border:1px solid var(--line);border-radius:10px;
  font-size:1rem;font-family:inherit;background:#fff;color:var(--ink);
}
select:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}
textarea{
  width:100%;padding:.65rem .7rem;
  border:1px solid var(--line);border-radius:10px;
  font-size:1rem;font-family:inherit;background:#fff;color:var(--ink);
  resize:vertical;min-height:96px;
}
textarea:focus{outline:2px solid var(--blue);outline-offset:1px;border-color:var(--blue)}

.planorder{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin:.55rem 0 .3rem}
.planorder label{font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);margin:0}
.planorder select{max-width:15rem;flex:1 1 12rem;margin:0}
.planorder button{width:auto;padding:.6rem 1.1rem;margin:0;flex:0 0 auto}
.pill{display:inline-block;font-size:.68rem;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;padding:.2rem .5rem;border-radius:999px;
  background:#f1f5f9;color:#475569;border:1px solid var(--line)}
.pill.ok{background:#dcfce7;color:#166534;border-color:#bbf7d0}
.pill.warn{background:#fef3c7;color:#92400e;border-color:#fde68a}
.warn-txt{color:var(--warn)}
.testbanner{background:#fef3c7;border:1px solid #fde68a;color:#92400e;
  font-size:.8rem;font-weight:600}
@media (max-width:640px){
  .planorder{flex-direction:column;align-items:stretch;gap:.35rem}
  .planorder select,.planorder button{max-width:100%;width:100%}
}
