:root{
--gr:{{C_GROUND}};--sa:{{C_SURFACE_ALT}};
--ik:{{C_INK}};--im:{{C_INK_MUTED}};--if:{{C_INK_FAINT}};
--ac:{{C_ACCENT}};--ai:{{C_ACCENT_INK}};--at:{{C_ACCENT_TEXT}};--aw:{{C_ACCENT_WASH}};
--ct:{{C_CRIT}};--ctt:{{C_CRIT_TEXT}};--cw:{{C_CRIT_WASH}}}
@media(prefers-color-scheme:dark){:root{
--gr:{{C_D_GROUND}};--sa:{{C_D_SURFACE_ALT}};
--ik:{{C_D_INK}};--im:{{C_D_INK_MUTED}};--if:{{C_D_INK_FAINT}};
--ac:{{C_D_ACCENT}};--ai:{{C_D_ACCENT_INK}};--at:{{C_D_ACCENT_TEXT}};--aw:{{C_D_ACCENT_WASH}};
--ct:{{C_D_CRIT}};--ctt:{{C_D_CRIT_TEXT}};--cw:{{C_D_CRIT_WASH}}}}
html[data-force-scheme=light]{
--gr:{{C_GROUND}};--sa:{{C_SURFACE_ALT}};
--ik:{{C_INK}};--im:{{C_INK_MUTED}};--if:{{C_INK_FAINT}};
--ac:{{C_ACCENT}};--ai:{{C_ACCENT_INK}};--at:{{C_ACCENT_TEXT}};--aw:{{C_ACCENT_WASH}};
--ct:{{C_CRIT}};--ctt:{{C_CRIT_TEXT}};--cw:{{C_CRIT_WASH}}}
html[data-force-scheme=dark]{
--gr:{{C_D_GROUND}};--sa:{{C_D_SURFACE_ALT}};
--ik:{{C_D_INK}};--im:{{C_D_INK_MUTED}};--if:{{C_D_INK_FAINT}};
--ac:{{C_D_ACCENT}};--ai:{{C_D_ACCENT_INK}};--at:{{C_D_ACCENT_TEXT}};--aw:{{C_D_ACCENT_WASH}};
--ct:{{C_D_CRIT}};--ctt:{{C_D_CRIT_TEXT}};--cw:{{C_D_CRIT_WASH}}}
*{box-sizing:border-box}
html{font-size:16px}
@media(min-width:600px){html{font-size:20px}}
/* Only the horizontal axis is clamped. The vertical axis has to stay
scrollable, because the change-password state adds two more fields and a
message box and grows taller than the viewport. Clamping both axes silently
cuts that state off. */
html,body{overflow-x:hidden!important}
/* The block-page shell centres with display:flex on the body. That cannot be
done here: login.esp is served with no DOCTYPE, so this page runs in QUIRKS
mode, where the body is the scrolling element -- and a body that is both the
scroller and a flex container stops scrolling once the change-password state
grows past the viewport. The centring moves onto .loginscreen_logo, which is
what every other portal shell does anyway. Measured: with flex on the body
the expiry message sat 214px below the fold and no wheel event reached it. */
body{margin:0;min-height:100vh;background:var(--gr);color:var(--ik);
border-top:.375rem solid transparent;
border-image:linear-gradient({{C_GRAD_ANGLE}},{{C_GRAD_FROM}},{{C_GRAD_TO}}) 1;
font:1rem/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
-webkit-font-smoothing:antialiased}
/* .loginscreen_logo is the wrapper the stock file uses. Keeping the class name
means the markup below still looks like the page PAN-OS shipped. */
.loginscreen_logo{width:100%;max-width:26rem;margin:0 auto;
padding:clamp(2rem,9vh,5rem) 1.5rem 3.5rem}
/* The mark, twice. An SVG behind url() renders as an isolated document --
currentColor is dead in there and these custom properties are out of scope --
so changing scheme means changing the whole asset. Doing that here rather
than inside the SVG is what lets data-force-scheme reach it, which is how one
machine previews both schemes. Each copy is written once and selected through
--lg; naming them in all four rule sets would carry the artwork four times. */
:root{--lgl:url("data:image/svg+xml,{{PORTAL_LOGO_LIGHT}}");
--lgd:url("data:image/svg+xml,{{PORTAL_LOGO_DARK}}");--lg:var(--lgl)}
@media(prefers-color-scheme:dark){:root{--lg:var(--lgd)}}
html[data-force-scheme=light]{--lg:var(--lgl)}
html[data-force-scheme=dark]{--lg:var(--lgd)}
/* The lockup: the mark painted by the stylesheet, the name beside it as live
text. Splitting them is what makes a rename in config reach this page -- an
SVG cannot measure text, so a name drawn into fixed artwork is a name that
gets clipped or shrunk. It also means only the mark needs a copy per scheme;
the text takes its colour from the cascade, inherited rather than stated,
because the one theme that stands this on the accent band has already set it.
Painting from CSS also puts it on screen at first paint: the body ships no
img and the logo variable is empty, so nothing here waits on jQuery. */
#logo{height:2.2rem;margin:0 0 2rem;display:flex;align-items:center;gap:.55rem;
font-size:1.02rem;font-weight:700;letter-spacing:-.01em;color:inherit}
#logo .mk{width:1.9rem;height:1.9rem;flex:none;
background:var(--lg) center/contain no-repeat}
#heading{margin:0 0 .55rem;font-size:1.85rem;line-height:1.15;letter-spacing:-.028em;
font-weight:650;color:var(--ik);text-align:left;font-family:inherit}
/* The portal name, carried in markup because gp_portal_name is applied with
.html() and would replace the switch spans beside it. */
#heading .pn{display:block;margin:0 0 .25rem;font-size:.62rem;font-weight:700;
letter-spacing:.14em;text-transform:uppercase;color:var(--at)}
.gloss{margin:0 0 2rem;color:var(--im);font-size:1rem;line-height:1.72}
/* Below: the markup the form token expands into. The ids are PAN-OS', not ours
-- loadPage() and submitClicked() look them up by id, so they are restyled in
place. The token is named in prose, never written literally outside the body:
PAN-OS substitutes the first occurrence in the file and does not care that it
is inside a comment. */
#formdiv{margin:0}
#taLogin{margin:0;padding:0;width:auto;min-height:0;background:none;border:0;
box-shadow:none;text-align:left}
.login_fields>div{width:auto;margin:0 0 .85rem}
#formdiv input[type=text],#formdiv input[type=password]{
display:block;width:100%;min-height:3rem;padding:.7rem .9rem;
font:inherit;font-size:.95rem;color:var(--ik);background:var(--gr);
border:1px solid var(--sa);border-radius:.6rem;-webkit-appearance:none;appearance:none;
transition:border-color .15s ease,box-shadow .15s ease}
#formdiv input[type=text]:focus,#formdiv input[type=password]:focus{
outline:0;border-color:var(--at);box-shadow:0 0 0 3px var(--aw)}
#formdiv input::placeholder{color:var(--if);opacity:1}
#submitbutton{margin:1.4rem 0 0}
#formdiv .buttonFixed{display:block;width:100%;min-height:3rem;margin:0;
padding:.75rem 1.5rem;font:inherit;font-size:.97rem;font-weight:600;
background:var(--ac);color:var(--ai);border:1px solid transparent;border-radius:.6rem;
cursor:pointer;-webkit-appearance:none;appearance:none}
#formdiv .buttonFixed:hover{filter:brightness(1.08)}
#dError,.error_msg{margin:1.3rem 0 0;padding:.9rem 1rem;border-radius:.75rem;
font:inherit;font-size:.87rem;line-height:1.55;color:var(--ik);background:var(--cw);
border-left:3px solid var(--ct);list-style:none}
/* loadPage() writes the failure text as an
with no list around it. */
#dError li{display:block;list-style:none}
#dInputStr{margin:0 0 .85rem;font-size:.9rem;color:var(--im)}
/* The two wrappers, listed by id. PAN-OS puts class="msg" on the inner div
as well, so a `#dChangePasswordMsgArea .msg` reset matches the message box
too -- and at one id plus one class it outranks the `#dChangePasswordMsg`
rule below, stripping the padding and the background off the box that
actually shows the text. Only the change-password state renders any of
this, so nothing catches it until a password expires. */
#dChangePasswordMsgArea,#dChangePasswordMsgBorder{max-width:none;margin:1.3rem 0 0;padding:0;background:none}
#dChangePasswordMsg{padding:.9rem 1rem;border-radius:.75rem;font-size:.87rem;
background:var(--sa);border-left:3px solid var(--at)}
/* --- getsoftwarepage.esp ------------------------------------------------
The portal serves this same imported file for the agent-download page and
swaps the form token for a different form. One file, two contexts, so the
copy switches with them: .pl shows on the login page, .ps on the download
page. Default is login -- if the detection script never runs, the page
degrades to the login wording rather than to nothing. */
.ps{display:none}
html[data-page=sw] .pl{display:none}
html[data-page=sw] .ps{display:inline}
/* The injected markup is 2005-era table layout with align/valign/width
attributes and an inline padding-top on the outer table. Inline styles
outrank a stylesheet, which is why the width, height and padding resets carry
!important -- the rest is beating presentational attributes, which do not. */
html[data-page=sw] table{width:100%!important;height:auto!important;
padding-top:0!important;border-collapse:collapse}
html[data-page=sw] td{padding:0;text-align:left;vertical-align:top}
#taGetSofewarePage p{margin:0 0 .55rem}
/* PAN-OS' own anchors, styled where they stand. All three weighted equally on
purpose: this rule set is the fallback, shown whenever the script below has
not replaced it, and a primary chosen here would have to be chosen by DOM
position -- PAN-OS lists Windows 32-bit first, so the accent would steer
people onto a 32-bit build. The anchors carry no class; p > a is the only
anchor shape in this form. */
#taGetSofewarePage p a{display:block;min-height:3rem;padding:.75rem 1rem;
font-size:.95rem;font-weight:600;text-align:center;text-decoration:none;
border-radius:.6rem;background:var(--sa);color:var(--at);border:1px solid var(--sa)}
#taGetSofewarePage p a:hover{filter:brightness(.97)}
/* --- the download button ---
Everything above is the page PAN-OS builds: three equal links over three rows
explaining which one to take, i.e. a decision the browser has already made.
The script at the end of the body reads the platform out of the user agent,
MOVES those anchors into the menu below -- moved, never rebuilt, so no href
is ever retyped and no markup is ever built in JS -- and puts the matching
one on this button.
None of this is visible until that script sets data-dl on the document, which
it does last. #dl ships hidden, so a thrown exception, a blocked script or a
platform nobody recognised leaves the working stock links in place rather
than an empty card. */
html[data-dl] #taGetSofewarePage p,
html[data-dl] #taGetSofewarePage table{display:none}
.dl[hidden]{display:none}
/* One-pixel gap rather than a border between the halves: they share a colour,
so a border would need its own contrasting value in every palette. */
.dlrow{display:flex;gap:1px}
.dlmain{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
min-height:3rem;padding:.75rem 1.2rem;font-size:.97rem;font-weight:600;text-decoration:none;
cursor:pointer;background:var(--ac);color:var(--ai);border:1px solid transparent;
border-radius:.6rem 0 0 .6rem;}
.dlmain svg{width:1.05rem;height:1.05rem;flex:none}
.dlcar{display:inline-flex;align-items:center;justify-content:center;width:2.6rem;
min-height:3rem;padding:0;font:inherit;cursor:pointer;
background:var(--ac);color:var(--ai);border:1px solid transparent;
border-radius:0 .6rem .6rem 0;-webkit-appearance:none;appearance:none}
.dlcar svg{width:1.1rem;height:1.1rem}
.dlmain:hover,.dlcar:hover{filter:brightness(1.08)}
.dlcar[aria-expanded=true] svg{transform:rotate(180deg)}
/* The focus rule at the foot of this file covers a and input. The caret is a
button, so it needs its own. */
.dlcar:focus-visible{outline:3px solid var(--at);outline-offset:3px}
.dlmenu{margin:.4rem 0 0;padding:.3rem;border-radius:.6rem;border:1px solid var(--sa);
background:var(--gr)}
.dlmenu[hidden]{display:none}
.dlitem{display:block;padding:.55rem .7rem;border-radius:.45rem;font-size:.88rem;
font-weight:600;color:var(--ik);text-decoration:none}
.dlitem:hover{background:var(--sa)}
/* The description rows are styled for that same fallback: three sentences
restating which build suits which OS, which is exactly what the button below
answers. Hidden with the links once the button is up. #dFormat is empty in
every capture. */
#taGetSofewarePage table{margin:1.1rem 0 0}
#taGetSofewarePage table td{padding:.35rem 0;font-size:.8rem;line-height:1.5;
color:var(--if);border-bottom:1px solid var(--sa)}
#dFormat{display:none}
.note{margin:2rem 0 0;font-size:.85rem;color:var(--if);line-height:1.6}
.note a{color:var(--at)}
a:focus-visible,input:focus-visible{outline:3px solid var(--at);outline-offset:3px}
@media(max-width:600px){
.loginscreen_logo{padding:1.75rem 1.15rem 2.5rem}
#logo{margin-bottom:1.6rem}
#heading{font-size:1.6rem}
.gloss{font-size:.95rem;margin-bottom:1.6rem}}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
{{COMPANY}}
{{PORTAL_NAME}}Sign inGet Agent Software
Use your company account to sign in.Download the agent for your operating system, then sign in from the app.
Need help? Contact {{CONTACT_NAME}}.
html[data-gp=logout]{
--gr:{{C_GROUND}};--sa:{{C_SURFACE_ALT}};
--ik:{{C_INK}};--im:{{C_INK_MUTED}};--if:{{C_INK_FAINT}};
--ac:{{C_ACCENT}};--ai:{{C_ACCENT_INK}};--at:{{C_ACCENT_TEXT}};--aw:{{C_ACCENT_WASH}};
font-size:16px;overflow-x:hidden}
@media(prefers-color-scheme:dark){html[data-gp=logout]{
--gr:{{C_D_GROUND}};--sa:{{C_D_SURFACE_ALT}};
--ik:{{C_D_INK}};--im:{{C_D_INK_MUTED}};--if:{{C_D_INK_FAINT}};
--ac:{{C_D_ACCENT}};--ai:{{C_D_ACCENT_INK}};--at:{{C_D_ACCENT_TEXT}};--aw:{{C_D_ACCENT_WASH}}}}
html[data-gp=logout][data-force-scheme=light]{
--gr:{{C_GROUND}};--sa:{{C_SURFACE_ALT}};
--ik:{{C_INK}};--im:{{C_INK_MUTED}};--if:{{C_INK_FAINT}};
--ac:{{C_ACCENT}};--ai:{{C_ACCENT_INK}};--at:{{C_ACCENT_TEXT}};--aw:{{C_ACCENT_WASH}}}
html[data-gp=logout][data-force-scheme=dark]{
--gr:{{C_D_GROUND}};--sa:{{C_D_SURFACE_ALT}};
--ik:{{C_D_INK}};--im:{{C_D_INK_MUTED}};--if:{{C_D_INK_FAINT}};
--ac:{{C_D_ACCENT}};--ai:{{C_D_ACCENT_INK}};--at:{{C_D_ACCENT_TEXT}};--aw:{{C_D_ACCENT_WASH}}}
html[data-gp=logout] *{box-sizing:border-box}
@media(min-width:600px){html[data-gp=logout]{font-size:20px}}
/* The gradient rule survives the move to a page with no markup: it is a border
on the body, and the body is one of the two elements PAN-OS always gives us.
Nothing else about this theme needs an element it does not have. */
html[data-gp=logout] body{margin:0;min-height:100vh;display:flex;justify-content:center;
padding:clamp(2rem,9vh,5rem) 1.5rem 3.5rem;
border-top:.375rem solid transparent;
border-image:linear-gradient({{C_GRAD_ANGLE}},{{C_GRAD_FROM}},{{C_GRAD_TO}}) 1;
background:var(--gr);color:var(--ik);
font:1rem/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
-webkit-font-smoothing:antialiased}
/* No card. .loginscreen_logo is the only wrapper available, and this theme
would put nothing around it on the login page either. */
html[data-gp=logout] .loginscreen_logo{width:100%;max-width:24rem;margin:0;padding:0;
text-align:left;background:none;border:0}
/* The logo is painted by CSS, not by the logo variable, and the img PAN-OS
wrote is hidden outright.
PAN-OS hard-codes its own mark into this body and its jQuery handler only
rewrites that src at ready. The browser has already fetched and painted the
Palo Alto logo by then, so the page visibly flashes the wrong one before
settling on ours. On the login page that was avoidable -- we own that body
and ship the img with no src -- but here the body is PAN-OS'. A stylesheet
applies at first paint, so moving the artwork into CSS removes the flash
entirely. The img is display:none rather than swapped, so its src never
matters, whatever jQuery does to it later.
The logo variable stays set even though this rule supersedes it: the same
variable brands the portal home page, which this file does not restyle. That
page gets the light copy and only the light copy -- it is an img src, and an
img has no way to be told which scheme it is in. Its Bootstrap chrome is
light either way, so that is the right copy. */
html[data-gp=logout]{--lgl:url("data:image/svg+xml,{{PORTAL_LOGO_LIGHT}}");
--lgd:url("data:image/svg+xml,{{PORTAL_LOGO_DARK}}");--lg:var(--lgl)}
@media(prefers-color-scheme:dark){html[data-gp=logout]{--lg:var(--lgd)}}
html[data-gp=logout][data-force-scheme=light]{--lg:var(--lgl)}
html[data-gp=logout][data-force-scheme=dark]{--lg:var(--lgd)}
/* PAN-OS owns this body, so the name cannot be put beside the mark as markup.
::before carries the artwork and ::after the text -- both on our own
stylesheet, which is the only way in. The img PAN-OS wrote is hidden rather
than swapped, so whatever its src ends up being never matters. */
html[data-gp=logout] #logo{height:2.2rem;margin:0 0 2rem;display:flex;align-items:center;gap:.55rem;
font-size:1.02rem;font-weight:700;letter-spacing:-.01em}
html[data-gp=logout] #logo::before{content:"";width:1.9rem;height:1.9rem;flex:none;
background:var(--lg) center/contain no-repeat}
html[data-gp=logout] #logo::after{content:"{{COMPANY_CSS}}"}
html[data-gp=logout] #logo img{display:none}
html[data-gp=logout] #heading{margin:0 0 1.2rem;font-size:1.85rem;line-height:1.15;
letter-spacing:-.028em;font-weight:650;color:var(--ik);text-align:left;font-family:inherit}
html[data-gp=logout] #formdiv{margin:0}
/* The message div. PAN-OS fills it from logout_text_array at ready, so it is
empty at parse time -- min-height stops the page reflowing when text lands. */
html[data-gp=logout] #logout{min-height:2.8rem;margin:0 0 1.7rem;padding:.9rem 1rem;
width:auto;font-family:inherit;font-size:.9rem;font-weight:400;line-height:1.6;
text-align:left;color:var(--ik);background:var(--sa);border-radius:.75rem}
html[data-gp=logout] #taLogout{margin:0;padding:0;width:auto;min-height:0;
background:none;border:0;box-shadow:none;text-align:left}
html[data-gp=logout] .buttonFixed-logout{display:block;width:100%;min-height:3rem;
margin:0;padding:.75rem 1.5rem;font:inherit;font-size:.97rem;font-weight:600;
background:var(--ac);color:var(--ai);border:1px solid transparent;border-radius:.6rem;
cursor:pointer;-webkit-appearance:none;appearance:none;text-transform:none}
html[data-gp=logout] .buttonFixed-logout:hover{filter:brightness(1.08)}
html[data-gp=logout] .buttonFixed-logout:focus-visible{outline:3px solid var(--at);
outline-offset:3px}
@media(max-width:600px){
html[data-gp=logout] body{padding:1.75rem 1.15rem 2.5rem}
html[data-gp=logout] #logo{margin-bottom:1.6rem}
html[data-gp=logout] #heading{font-size:1.6rem}}
@media(prefers-reduced-motion:reduce){
html[data-gp=logout] *{animation:none!important;transition:none!important}}