/* Sara Sadeghi Portfolio
   One screen, one object: a chrome puzzle cube in black space. Type stays small and at the edges.

   Sections
   1. tokens and base
   2. stage and corner UI (name, nav, project list, controls)
   3. the panel (project / about / contact / hidden)
   4. panel content
   5. layouts: side panel in landscape, bottom sheet in portrait, compact on phones
*/

/* 1. tokens and base ----------------------------------------------------- */
:root{
  --ink:#050506;
  --panel:#0A0A0B;
  --fg:#F2F3F4;
  --dim:#9B9EA4;
  --line:rgba(255,255,255,.14);
  --f:'Jost','Century Gothic','Avenir Next','Helvetica Neue',sans-serif;
  --pad:clamp(18px,3vw,40px);
  --sl:env(safe-area-inset-left,0px);
  --sr:env(safe-area-inset-right,0px);
  --sb:env(safe-area-inset-bottom,0px);
  --pw:50%;   /* panel width, landscape */
  --ph:50%;   /* panel height, portrait */
  color-scheme:dark;
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--ink);color:var(--fg);font-family:var(--f);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;overflow:hidden}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;text-align:left}
a{color:inherit}
:focus-visible{outline:1px solid #fff;outline-offset:4px}
.cap{font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:400}

/* 2. stage and corner UI ------------------------------------------------- */
.stage{position:relative;height:100vh;height:100dvh;overflow:hidden;background:radial-gradient(52% 50% at 50% 48%,#141518 0%,#08080A 55%,#050506 100%)}
#gl{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none;cursor:grab}
#gl.drag{cursor:grabbing}
#gl.hit{cursor:pointer}
@media (hover:hover) and (pointer:fine){#gl,#gl.drag,#gl.hit{cursor:none}}
/* the light the cursor carries */
.glow{position:absolute;width:min(70vw,1000px);height:min(70vw,1000px);border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;background:radial-gradient(circle,rgba(255,255,255,.09),rgba(255,255,255,.025) 32%,rgba(255,255,255,0) 60%);transition:opacity .5s;opacity:0}
.glow.on{opacity:1}
.ui{position:absolute;pointer-events:none}
.ui>*{pointer-events:auto}

.brand{left:calc(var(--pad) + var(--sl));top:var(--pad)}
.brand h1{margin:0;font-weight:500;font-size:clamp(22px,2.2vw,30px);line-height:1;letter-spacing:-.01em}
.brand p{margin:10px 0 0;color:var(--dim)}
.info{width:26px;height:26px;border:1px solid rgba(255,255,255,.5);border-radius:50%;display:flex;align-items:center;justify-content:center;font:italic 500 13px Georgia,"Times New Roman",serif;color:var(--fg);transition:background .25s,color .25s}
.info[aria-expanded=true],.info:hover{background:#fff;color:#000}
.tips{position:absolute;right:0;top:calc(100% + 14px);padding:14px 16px;border:1px solid var(--line);background:rgba(10,10,11,.92);color:var(--dim);line-height:1.6;width:max-content;max-width:min(300px,80vw);text-align:left;text-transform:none;letter-spacing:.04em;font-size:13px}
.tips p{margin:0}
.tips .low{opacity:.55;margin-top:6px}

.nav{right:calc(var(--pad) + var(--sr));top:var(--pad);display:flex;align-items:center;gap:clamp(18px,2.4vw,34px)}
.nav button{padding:6px 0;border-bottom:1px solid transparent}

/* the project list: one centred row under the cube (wraps to two on narrower screens); it fades out while a panel is open */
.index{left:50%;bottom:calc(var(--pad) + var(--sb) + 62px);transform:translateX(-50%);width:max-content;max-width:calc(100% - 2*var(--pad));margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:2px clamp(16px,2.2vw,34px);transition:opacity .45s,visibility .45s}
.index .hd{flex:0 0 100%;text-align:center;color:var(--dim);padding:0 0 8px}
.index button{display:flex;gap:10px;align-items:baseline;padding:5px 0;color:var(--dim);transition:color .25s;font-size:14px;letter-spacing:.01em;white-space:nowrap}
.index button span{font-size:11px;letter-spacing:.14em;font-variant-numeric:tabular-nums;opacity:.7}
.index button.on{color:#fff}
.stage.open .index{opacity:0;visibility:hidden}

/* the button, centred under the list */
.ctl{left:50%;bottom:calc(var(--pad) + var(--sb));transform:translateX(-50%);transition:left .6s cubic-bezier(.2,.8,.2,1)}
.ctl button{border:1px solid rgba(255,255,255,.5);border-radius:999px;padding:11px 22px;min-height:44px}

/* the copyright line, bottom left on desktop and iPad; phones have no room for it, there it sits at the end of Contact */
.copy{left:calc(var(--pad) + var(--sl));bottom:calc(var(--pad) + var(--sb));margin:0;color:var(--dim);font-size:11px;line-height:44px;white-space:nowrap}
.panel-body .fine{margin:44px 0 0;color:var(--dim);font-size:11px;letter-spacing:.04em;line-height:1.4}

/* the cursor over the cube: a ring, and one word for what a click or a drag does here */
.cur{position:absolute;left:0;top:0;width:16px;height:16px;margin:-8px 0 0 -8px;border:1px solid rgba(255,255,255,.55);border-radius:50%;pointer-events:none;z-index:4;transition:width .2s,height .2s,margin .2s,border-color .2s}
.cur b{position:absolute;left:24px;top:50%;transform:translateY(-50%);font-weight:400;font-size:11px;white-space:nowrap;color:rgba(255,255,255,.7);text-shadow:0 0 8px rgba(0,0,0,.95),0 0 2px rgba(0,0,0,.9)}
.cur.big{width:26px;height:26px;margin:-13px 0 0 -13px;border-color:rgba(255,255,255,.9)}
.cur.big b{left:34px;color:#fff}

.nogl{position:absolute;left:var(--pad);right:var(--pad);top:40%;color:var(--dim);text-align:center}

@media (hover:hover){
  .nav button:hover{border-bottom-color:#fff}
  .index button:hover{color:#fff}
  .ctl button:hover{background:#fff;color:#000}
}

/* 3. the panel ----------------------------------------------------------- */
.panel{position:absolute;right:0;top:0;bottom:0;width:var(--pw);background:var(--panel);border-left:1px solid var(--line);transform:translateX(102%);transition:transform .6s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column;z-index:5}
.panel.on{transform:none}
.panel-bar{display:flex;justify-content:space-between;align-items:center;padding:14px clamp(20px,3vw,36px);border-bottom:1px solid var(--line);flex:none;touch-action:pan-x;user-select:none}
.panel-bar div{display:flex;gap:22px}
.panel-bar button{padding:8px 0;min-height:36px;border-bottom:1px solid transparent}
.panel-body{overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:clamp(22px,3vw,36px) clamp(20px,3vw,36px) calc(56px + var(--sb));flex:1 1 auto;min-height:0}
@media (hover:hover){.panel-bar button:hover{border-bottom-color:#fff}}

/* 4. panel content -------------------------------------------------------
   one type scale: the title, one body size for every paragraph, small caps for headings and captions.
   text runs the full width of the panel, the same width as the images. */
.panel-body{--body:16px}
.panel-body h2{margin:0 0 22px;font-weight:500;font-size:clamp(26px,2.6vw,38px);line-height:1.1;letter-spacing:-.01em;text-wrap:balance}
.panel-body p,.panel-body .lead,.panel-body li,.panel-body dd,.panel-body blockquote{font-size:var(--body);line-height:1.6;font-weight:300}
.panel-body p{margin:0 0 16px;color:#D3D5D8}
.panel-body .lead{color:var(--fg);font-weight:400;margin:0 0 20px}
.panel-body h3{margin:38px 0 12px;padding-bottom:10px;border-bottom:1px solid var(--line);color:var(--fg)}
.panel-body figure{margin:0 0 24px}
.panel-body img{display:block;width:100%;height:auto}
.panel-body figcaption{color:var(--dim);margin-top:10px;letter-spacing:.12em}
.panel-body figure.small img{max-width:340px}
.pair{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:0 0 24px}
.pair figure{margin:0}
.pair img{max-height:none;aspect-ratio:4/5;object-fit:cover;object-position:center}
.pair.wide img{aspect-ratio:3/2}
/* a board: the images sit in one row, all at the proportion of the first one, so they line up */
.board>div{display:grid;grid-template-columns:repeat(var(--n,3),1fr);gap:12px}
.board figure{margin:0}
.board img{aspect-ratio:var(--r,4/5);object-fit:cover;object-position:center}
blockquote{margin:28px 0;padding:0 0 0 18px;border-left:1px solid rgba(255,255,255,.5);color:var(--fg)}
.act{margin:8px 0 28px}
/* video: a Vimeo film shows a poster and a play ring until it is pressed; a file from this site plays in place */
.vid{margin:0 0 24px}
.vid video,.vid iframe,.vf{display:block;width:100%;aspect-ratio:16/9;background:#000;border:0;border-radius:8px}
.vf{position:relative;overflow:hidden;padding:0;cursor:pointer}
.vf img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.85}
.vf .play{position:absolute;left:50%;top:50%;width:64px;height:64px;margin:-32px 0 0 -32px;border:1px solid rgba(255,255,255,.8);border-radius:50%;transition:background .25s}
.vf .play::after{content:"";position:absolute;left:50%;top:50%;margin:-9px 0 0 -6px;border-left:15px solid #fff;border-top:9px solid transparent;border-bottom:9px solid transparent}
.vf:hover .play{background:rgba(255,255,255,.18)}
/* a company logo after its name. it only shows when images/logos/<name>.svg (painted chrome) or .png (shown as it is) exists */
.logo{display:none;width:22px;height:22px;vertical-align:-6px;margin-left:.5em;background:linear-gradient(160deg,#f6f7f8 0%,#c3c6cb 32%,#5f626a 50%,#cfd2d7 66%,#ffffff 100%);-webkit-mask-size:contain;mask-size:contain;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
.logo.on{display:inline-block}
.panel-bar .logo{width:24px;height:24px;vertical-align:-7px}

.spec{margin:26px 0 0;border-bottom:1px solid var(--line)}
.spec div{display:flex;gap:16px;padding:11px 0;border-top:1px solid var(--line)}
.spec dt{flex:0 0 112px;color:var(--dim);padding-top:3px}
.spec dd{margin:0;min-width:0}

.rows{list-style:none;margin:0;padding:0}
.rows li{padding:9px 0;border-bottom:1px solid var(--line)}
.rows li span{display:block;color:var(--dim);margin-top:2px}

.qa details{border-bottom:1px solid var(--line)}
.qa summary{cursor:pointer;list-style:none;padding:13px 0;font-weight:500;display:flex;justify-content:space-between;gap:12px}
.qa summary::-webkit-details-marker{display:none}
.qa summary::after{content:"+";font-weight:300}
.qa details[open] summary::after{content:"\2212"}

/* contact: the address is the biggest thing on the page, the links sit in the same table as the specs elsewhere */
.cmail{display:block;margin:30px 0 4px;font-weight:300;font-size:clamp(23px,2.6vw,36px);line-height:1.15;letter-spacing:-.01em;color:var(--fg);text-decoration:none;overflow-wrap:anywhere;user-select:all}
.ccopy{color:var(--dim);padding:6px 0;margin:0 0 12px;border-bottom:1px solid transparent;transition:color .25s,border-color .25s}
.spec dd a{text-decoration:none}
.spec dd a::after{content:"\2197";margin-left:8px;color:var(--dim);font-size:12px}
@media (hover:hover){
  .cmail:hover{text-decoration:underline;text-underline-offset:7px;text-decoration-thickness:1px}
  .ccopy:hover{color:#fff;border-bottom-color:#fff}
  .spec dd a:hover{text-decoration:underline;text-underline-offset:4px}
}
.pill{border:1px solid rgba(255,255,255,.5);border-radius:999px;padding:9px 18px;min-height:44px;display:inline-flex;align-items:center;text-decoration:none}
@media (hover:hover){.pill:hover{background:#fff;color:#000}}

.riddle{margin:0 0 22px;padding:0;list-style:none;counter-reset:r}
.riddle li{counter-increment:r;padding:11px 0;border-top:1px solid var(--line);font-size:18px;font-weight:300;display:flex;gap:16px}
.riddle li::before{content:counter(r,upper-roman);color:var(--dim);font-size:12px;letter-spacing:.14em;width:22px;padding-top:6px}
.code{display:flex;gap:10px;margin:0 0 18px}
.code div{display:flex;flex-direction:column;align-items:center;gap:8px}
.code label{color:var(--dim)}
.code input{width:58px;height:72px;text-align:center;font:300 34px var(--f);color:#fff;background:#000;border:1px solid rgba(255,255,255,.5);border-radius:6px}
.code input:focus{outline:1px solid #fff;outline-offset:2px}
.code.bad{animation:shake .4s}
@keyframes shake{20%{transform:translateX(-8px)}40%{transform:translateX(7px)}60%{transform:translateX(-4px)}80%{transform:translateX(2px)}}
.slot{border:1px dashed rgba(255,255,255,.5);padding:18px;color:var(--dim)}

.stage.lock .ctl{visibility:hidden}

/* 5. layouts ------------------------------------------------------------- */
/* landscape (desktop, laptop, iPad landscape): the panel is the right half, the button moves to the corner beside it */
.stage.open .ctl{left:calc((100% - var(--pw)) / 2)}

/* portrait (iPad upright, phones): the panel is a sheet that rises from the bottom */
@media (orientation:portrait){
  .panel{left:0;right:0;top:auto;bottom:0;width:auto;height:var(--ph);border-left:0;border-top:1px solid var(--line);transform:translateY(102%);background:rgba(10,10,11,.97)}
  .panel.on{transform:none}
  .panel-bar{touch-action:pan-y}
  .stage.open .ctl{left:50%}
  .stage.open .index,.stage.open .ctl{visibility:hidden}
}

/* compact: phones in either orientation */
@media (max-width:700px),(max-height:520px){
  :root{--ph:60%}
  .copy{display:none}
  .brand p{max-width:180px}
  .index{left:calc(var(--pad) + var(--sl));right:calc(var(--pad) + var(--sr));transform:none;width:auto;max-width:none;display:grid;grid-template-columns:auto auto;justify-content:center;column-gap:24px;bottom:calc(var(--pad) + var(--sb) + 60px)}
  .index .hd{grid-column:1/-1;text-align:center;padding:0 0 4px}
  .index button{font-size:13px;padding:3px 0;gap:8px}
  .index button span{width:20px}
  .stage.open .index,.stage.open .ctl{visibility:hidden}
  .tips{max-width:min(260px,80vw)}
  .panel-body h2{font-size:26px}
  .pair{grid-template-columns:1fr;gap:12px}
  .board>div{grid-template-columns:repeat(var(--nc,var(--n,3)),1fr)}
}

/* phones held sideways: very little height, so the list goes tight and the name loses its line */
@media (max-height:520px){
  .brand p{display:none}
  .index .hd{display:none}
  .index{bottom:calc(var(--pad) + var(--sb));right:auto;grid-template-columns:repeat(5,auto);column-gap:26px}
  .index button{padding:2px 0}
  .ctl{left:auto;right:calc(var(--pad) + var(--sr));transform:none}
  .stage.open .ctl{left:auto}
  .panel-bar{padding-top:8px;padding-bottom:8px}
}

@media (max-height:520px) and (max-width:700px){
  .index{right:calc(var(--pad) + var(--sr) + 145px);grid-template-columns:repeat(2,auto);column-gap:clamp(10px,2vw,20px)}
}

/* touch: comfortable targets */
@media (pointer:coarse){
  .nav button[data-open],.panel-bar button{min-height:44px}
  .nav .info{width:28px;height:28px;min-height:0}
  .index button{padding:4px 0}
}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
