prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

experience.css (8927B)


      1 #experience {
      2   width: 100%;
      3 }
      4 
      5 .experience-layout {
      6   display: flex;
      7   flex-direction: row;
      8   height: 100%;
      9   width: 100%;
     10   padding: 24px 32px;
     11   gap: 24px;
     12   justify-content: center;
     13 }
     14 
     15 .experience-detail {
     16   flex: 0 1 980px;
     17   width: 100%;
     18   overflow-y: auto;
     19   display: flex;
     20   flex-direction: column;
     21   gap: 16px;
     22   padding: 4px 20px 4px 4px;
     23 }
     24 
     25 .exp-row {
     26   display: flex;
     27 }
     28 
     29 .exp-card {
     30   background: var(--bg-alt);
     31   border: 2px solid var(--border);
     32   border-radius: 4px;
     33   padding: 24px;
     34   flex: 1;
     35   min-width: 0;
     36   display: flex;
     37   flex-direction: column;
     38   transition: border-color 80ms linear;
     39 }
     40 
     41 .exp-row.active .exp-card {
     42   border-color: var(--accent);
     43 }
     44 
     45 /*
     46  * Timeline strip: one lane per job on a shared month axis.
     47  *
     48  *   hark        |        |       |  ======|  9 mo
     49  *   mandolin    |      ==|=======|==      |  1 yr 5 mo
     50  *   amplifier   |  ==    |       |        |  3 mo
     51  *               2024     2025    2026   now
     52  *
     53  * A bar fills its start month through its end month. Each lane is a link
     54  * to its job and lights up together with the job's card.
     55  */
     56 .exp-chart {
     57   --name-w: 18ch;
     58   --dur-w: 10ch;
     59   position: sticky;
     60   top: -4px;
     61   z-index: 1;
     62   display: grid;
     63   grid-template-columns: var(--name-w) minmax(0, 1fr) var(--dur-w);
     64   column-gap: 2ch;
     65   /* sit beside the graph rail, never over it: start at the card's edge and
     66      line the lanes up with the card text */
     67   padding: 12px 24px 8px;
     68   margin: -4px 0 0 3ch;
     69   background: var(--bg);
     70   border-bottom: 1px solid var(--border);
     71   font-size: var(--fs-14);
     72   line-height: 1.5;
     73   user-select: none;
     74 }
     75 
     76 .chart-grid {
     77   grid-column: 2;
     78   position: relative;
     79   pointer-events: none;
     80 }
     81 
     82 .grid-line {
     83   position: absolute;
     84   top: 0;
     85   bottom: 0;
     86   left: var(--at);
     87   width: 1px;
     88   background: var(--border);
     89 }
     90 
     91 .exp-lane {
     92   grid-column: 1 / -1;
     93   display: grid;
     94   grid-template-columns: subgrid;
     95   align-items: center;
     96   color: var(--fg-dim);
     97   text-decoration: none;
     98   border-radius: 2px;
     99   outline-offset: 2px;
    100   -webkit-tap-highlight-color: transparent;
    101 }
    102 
    103 .exp-lane:hover {
    104   text-decoration: none;
    105 }
    106 
    107 .exp-lane:focus-visible {
    108   outline: 1px solid var(--accent);
    109 }
    110 
    111 .lane-name {
    112   overflow: hidden;
    113   text-overflow: ellipsis;
    114   white-space: nowrap;
    115 }
    116 
    117 .lane-dur {
    118   text-align: right;
    119   white-space: nowrap;
    120 }
    121 
    122 .lane-track {
    123   position: relative;
    124   height: 1.5em;
    125 }
    126 
    127 .exp-bar {
    128   position: absolute;
    129   top: 50%;
    130   left: var(--from);
    131   width: calc(var(--to) - var(--from));
    132   min-width: 4px;
    133   height: 6px;
    134   transform: translateY(-50%);
    135   background: var(--fg-dim);
    136   transition: background-color 80ms linear;
    137 }
    138 
    139 /* start and end caps: |=====| */
    140 .exp-bar::before,
    141 .exp-bar::after {
    142   content: "";
    143   position: absolute;
    144   top: -4px;
    145   bottom: -4px;
    146   width: 2px;
    147   background: inherit;
    148 }
    149 
    150 .exp-bar::before {
    151   left: 0;
    152 }
    153 
    154 .exp-bar::after {
    155   right: 0;
    156 }
    157 
    158 /* still running: no end cap, the bar runs into the "now" edge */
    159 .exp-bar.current::after {
    160   display: none;
    161 }
    162 
    163 .exp-lane.active {
    164   color: var(--accent);
    165 }
    166 
    167 .exp-lane.active .exp-bar {
    168   background: var(--accent);
    169 }
    170 
    171 .chart-axis {
    172   grid-column: 2;
    173   color: var(--fg-dim);
    174   font-size: var(--fs-12);
    175 }
    176 
    177 .axis-labels {
    178   position: relative;
    179   display: block;
    180   height: 1.5em;
    181 }
    182 
    183 .axis-tick {
    184   position: absolute;
    185   left: var(--at);
    186   padding-left: 4px;
    187   white-space: nowrap;
    188 }
    189 
    190 .axis-end {
    191   position: absolute;
    192   right: 0;
    193   white-space: nowrap;
    194 }
    195 
    196 /*
    197  * Graph rail, jj log style: one continuous line down the list with a node
    198  * on each job's role line, newest first, ending at the oldest.
    199  *
    200  *   @  hark / ...
    201  *   │
    202  *   *  mandolin / ...
    203  *   │
    204  *   *  amplifier health / ...
    205  *
    206  * Dates live on the cards, so the rail carries only the shape. The active
    207  * job lights its node and the line down to the job before it.
    208  */
    209 .exp-timeline {
    210   --row: 1.5em;
    211   --node-top: 46px; /* card border + padding + role line, beside the logo */
    212   flex-shrink: 0;
    213   width: 3ch;
    214   position: relative;
    215   font-size: var(--fs-14);
    216   line-height: 1.5;
    217   font-variant-ligatures: none;
    218   font-feature-settings: "liga" 0, "calt" 0;
    219   font-synthesis: none;
    220   color: var(--fg-dim);
    221   cursor: default;
    222   user-select: none;
    223 }
    224 
    225 .exp-row:has(.logo-hark) .exp-timeline {
    226   --node-top: 39px;
    227 }
    228 
    229 .graph-node {
    230   position: absolute;
    231   left: 0;
    232   width: 1ch;
    233   height: var(--row);
    234   text-align: center;
    235 }
    236 
    237 .graph-node {
    238   top: var(--node-top);
    239   transition: color 80ms linear;
    240 }
    241 
    242 /* hairline through the node column, broken around each node */
    243 .exp-row + .exp-row .exp-timeline::before,
    244 .exp-row:not(:last-child) .exp-timeline::after {
    245   content: "";
    246   position: absolute;
    247   left: calc(0.5ch - 0.5px);
    248   width: 1px;
    249   background: var(--border);
    250   transition: background-color 80ms linear;
    251 }
    252 
    253 /* from the previous job's line, across the gap, down to this node */
    254 .exp-row + .exp-row .exp-timeline::before {
    255   top: -16px;
    256   height: calc(16px + var(--node-top));
    257 }
    258 
    259 /* from under this node to the bottom of the row */
    260 .exp-row:not(:last-child) .exp-timeline::after {
    261   top: calc(var(--node-top) + var(--row));
    262   bottom: 0;
    263 }
    264 
    265 .exp-row.active .graph-node {
    266   color: var(--accent);
    267 }
    268 
    269 .exp-row.active .exp-timeline::after,
    270 .exp-row.active + .exp-row .exp-timeline::before {
    271   background: var(--accent-dim);
    272 }
    273 
    274 @media (prefers-reduced-motion: reduce) {
    275   .exp-card,
    276   .exp-bar,
    277   .graph-node,
    278   .exp-timeline::before,
    279   .exp-timeline::after {
    280     transition: none;
    281   }
    282 }
    283 
    284 .exp-card-header {
    285   display: grid;
    286   grid-template-columns: minmax(0, 1fr) auto;
    287   align-items: flex-start;
    288   gap: 12px 24px;
    289 }
    290 
    291 .exp-card-title {
    292   min-width: 0;
    293 }
    294 
    295 .exp-title-with-logo {
    296   display: flex;
    297   align-items: flex-start;
    298   gap: 12px;
    299   min-width: 0;
    300 }
    301 
    302 .exp-logo {
    303   height: 44px;
    304   width: auto;
    305   max-width: 180px;
    306   object-fit: contain;
    307   flex-shrink: 0;
    308 }
    309 
    310 .exp-logo.logo-hark {
    311   height: 30px;
    312   max-width: 140px;
    313 }
    314 
    315 .exp-logo.logo-invert {
    316   filter: brightness(0) invert(1);
    317   opacity: 0.9;
    318 }
    319 
    320 .exp-title-text {
    321   display: flex;
    322   align-items: center;
    323   gap: 10px;
    324   flex-wrap: wrap;
    325   min-width: 0;
    326 }
    327 
    328 .exp-title-text h2 {
    329   font-size: var(--fs-22);
    330   font-weight: 500;
    331   color: var(--accent);
    332   margin: 0;
    333   line-height: 1.1;
    334 }
    335 
    336 .exp-role {
    337   display: inline-flex;
    338   align-items: center;
    339   color: var(--accent);
    340   font-size: var(--fs-15);
    341   font-weight: 500;
    342   white-space: nowrap;
    343   line-height: 1.2;
    344 }
    345 
    346 .exp-role::before {
    347   content: "/";
    348   color: var(--yellow);
    349   margin-right: 4px;
    350 }
    351 
    352 .exp-role::after {
    353   content: "";
    354 }
    355 
    356 .exp-title-with-logo .exp-role {
    357   font-size: var(--fs-16);
    358   line-height: 1.1;
    359   margin-top: 22px;
    360 }
    361 
    362 .exp-logo.logo-hark + .exp-role {
    363   margin-top: 15px;
    364 }
    365 
    366 .exp-card-meta {
    367   display: flex;
    368   flex-direction: column;
    369   align-items: flex-end;
    370   gap: 3px;
    371   font-size: var(--fs-14);
    372   text-align: right;
    373   white-space: nowrap;
    374 }
    375 
    376 .exp-duration {
    377   color: var(--fg-dim);
    378 }
    379 
    380 .exp-card-tech {
    381   display: flex;
    382   flex-wrap: wrap;
    383   gap: 6px;
    384   margin-bottom: 20px;
    385 }
    386 
    387 .exp-card-body {
    388   color: var(--fg);
    389   line-height: 1.7;
    390 }
    391 
    392 .exp-card-body p {
    393   margin-bottom: 12px;
    394 }
    395 
    396 .exp-card-images {
    397   display: flex;
    398   gap: 12px;
    399   margin-top: 12px;
    400   padding-top: 12px;
    401   border-top: 1px solid var(--border);
    402   max-height: 200px;
    403   overflow: hidden;
    404 }
    405 
    406 .exp-image-hero {
    407   max-width: 280px;
    408   height: 100%;
    409   border-radius: 4px;
    410   border: 1px solid var(--border);
    411   object-fit: cover;
    412   cursor: pointer;
    413 }
    414 
    415 .exp-image-grid {
    416   display: flex;
    417   flex-wrap: wrap;
    418   gap: 8px;
    419   max-width: 400px;
    420 }
    421 
    422 .exp-image-thumb {
    423   width: calc(50% - 4px);
    424   height: 86px;
    425   border-radius: 4px;
    426   border: 1px solid var(--border);
    427   object-fit: cover;
    428   cursor: pointer;
    429 }
    430 
    431 .external-link {
    432   color: var(--light-blue);
    433   font-size: var(--fs-14);
    434   max-width: 36ch;
    435   overflow: hidden;
    436   text-overflow: ellipsis;
    437 }
    438 
    439 @media (max-width: 768px) {
    440   .experience-layout {
    441     padding: 16px;
    442     gap: 12px;
    443   }
    444 
    445   .exp-timeline {
    446     display: none;
    447   }
    448 
    449   .exp-chart {
    450     --name-w: 9ch;
    451     --dur-w: 9ch;
    452     position: static;
    453     column-gap: 1ch;
    454     margin: 0;
    455     padding: 0 0 8px;
    456     border-bottom: 0;
    457   }
    458 
    459   .lane-track,
    460   .exp-lane {
    461     min-height: 2em;
    462   }
    463 
    464   .exp-card {
    465     padding: 16px;
    466   }
    467 
    468   .experience-detail {
    469     padding: 4px 14px 4px 0;
    470   }
    471 
    472   .exp-card-header {
    473     grid-template-columns: 1fr;
    474     gap: 10px;
    475   }
    476 
    477   .exp-title-with-logo {
    478     align-items: flex-start;
    479   }
    480 
    481   .exp-logo {
    482     height: 38px;
    483     max-width: 150px;
    484     margin-top: 0;
    485   }
    486 
    487   .exp-logo.logo-hark {
    488     height: 26px;
    489     max-width: 120px;
    490   }
    491 
    492   .exp-title-with-logo .exp-role {
    493     margin-top: 19px;
    494   }
    495 
    496   .exp-logo.logo-hark + .exp-role {
    497     margin-top: 13px;
    498   }
    499 
    500   .exp-card-meta {
    501     align-items: flex-start;
    502     text-align: left;
    503     white-space: normal;
    504   }
    505 
    506   .exp-card-images {
    507     flex-direction: column;
    508     max-height: none;
    509     overflow: visible;
    510   }
    511 
    512   .exp-image-hero {
    513     max-width: 100%;
    514     height: auto;
    515     max-height: 200px;
    516   }
    517 
    518   .exp-image-thumb {
    519     width: calc(33.33% - 6px);
    520     height: 80px;
    521   }
    522 }