website: add back some resources
854
docs/r/base.css
Normal file
@ -0,0 +1,854 @@
|
||||
:root {
|
||||
--fontSize: 15px;
|
||||
/*--emsAcrossViewport: 80;
|
||||
--fontSize: calc(100vw / var(--emsAcrossViewport));*/
|
||||
|
||||
--lineHeight: calc(var(--fontSize) * 1.5);
|
||||
|
||||
--spacing: 2rem;
|
||||
--spacingv: calc(var(--lineHeight) / 2);
|
||||
|
||||
--columnGap: 2rem;
|
||||
|
||||
/* colors */
|
||||
--red: color(display-p3 0.94 0.19 0.04);
|
||||
--yellow: color(display-p3 1 0.96 0.05);
|
||||
--warm-yellow: color(display-p3 1 0.87 0.05);
|
||||
--light-yellow: color(display-p3 1 1 0.7);
|
||||
--blue: rgb(3, 102, 230);
|
||||
--green: rgb(38, 220, 78);
|
||||
--mediumGreen: rgb(119, 221, 134);
|
||||
}
|
||||
|
||||
@supports not (color: color(display-p3 1 1 1)) {
|
||||
/* sRGB colors */
|
||||
:root {
|
||||
--red: #F03009;
|
||||
--yellow: #FFF310;
|
||||
--warm-yellow: #FFE310;
|
||||
--light-yellow: rgb(255, 255, 179);
|
||||
}
|
||||
}
|
||||
|
||||
* { margin:0; padding:0; font-synthesis: none; }
|
||||
|
||||
html.debug *:nth-child(4n) { outline:1px solid rgba(0,0,255,0.5); }
|
||||
html.debug *:nth-child(4n+1) { outline:1px solid rgba(0,255,255,0.5); }
|
||||
html.debug *:nth-child(4n+2) { outline:1px solid rgba(255,0,255,0.5); }
|
||||
html.debug *:nth-child(4n+3) { outline:1px solid rgba(255,0,0,0.5); }
|
||||
|
||||
html { }
|
||||
body {
|
||||
background-color: #f4f4f4;
|
||||
color: #111;
|
||||
font: 15px/22px 'Inter', system-ui, sans-serif;
|
||||
|
||||
/*font-size: 15px;
|
||||
line-height: 1.5;*/
|
||||
|
||||
font-size: var(--fontSize);
|
||||
line-height: var(--lineHeight);
|
||||
|
||||
letter-spacing: -0.004em;
|
||||
|
||||
font-weight: 400;
|
||||
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
font-kerning: normal;
|
||||
-webkit-font-kerning: normal;
|
||||
-ms-font-kerning: normal;
|
||||
-moz-font-kerning: normal;
|
||||
-o-font-kerning: normal;
|
||||
|
||||
font-variant-ligatures: contextual common-ligatures;
|
||||
-webkit-font-variant-ligatures: contextual common-ligatures;
|
||||
-ms-font-variant-ligatures: contextual common-ligatures;
|
||||
-moz-font-variant-ligatures: contextual common-ligatures;
|
||||
-o-font-variant-ligatures: contextual common-ligatures;
|
||||
|
||||
/* required to work around letter-spacing bug in Chrome: */
|
||||
font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
|
||||
}
|
||||
|
||||
/* Font style classifiers used by samples and dynmetrics */
|
||||
/* Note: font-variation-settings is needed for Safari. */
|
||||
.font-style-thin { font-variation-settings: "wght" 100, "slnt" 0 !important; font-weight:100 !important; font-style:normal !important; }
|
||||
.font-style-thin-italic { font-variation-settings: "wght" 100, "slnt" 100 !important; font-weight:100 !important; font-style:oblique !important; }
|
||||
.font-style-extra-light { font-variation-settings: "wght" 200, "slnt" 0 !important; font-weight:100 !important; font-style:normal !important; }
|
||||
.font-style-extra-light-italic { font-variation-settings: "wght" 200, "slnt" 100 !important; font-weight:100 !important; font-style:oblique !important; }
|
||||
.font-style-light { font-variation-settings: "wght" 300, "slnt" 0 !important; font-weight:300 !important; font-style:normal !important; }
|
||||
.font-style-light-italic { font-variation-settings: "wght" 300, "slnt" 100 !important; font-weight:300 !important; font-style:oblique !important; }
|
||||
.font-style-regular { font-variation-settings: "wght" 400, "slnt" 0 !important; font-weight:400 !important; font-style:normal !important; }
|
||||
.font-style-italic { font-variation-settings: "wght" 400, "slnt" 100 !important; font-weight:400 !importants; font-style:oblique !important; }
|
||||
.font-style-medium { font-variation-settings: "wght" 500, "slnt" 0 !important; font-weight:500 !important; font-style:normal !important; }
|
||||
.font-style-medium-italic { font-variation-settings: "wght" 500, "slnt" 100 !important; font-weight:500 !important; font-style:oblique !important; }
|
||||
.font-style-semi-bold { font-variation-settings: "wght" 600, "slnt" 0 !important; font-weight:600 !important; font-style:normal !important; }
|
||||
.font-style-semi-bold-italic { font-variation-settings: "wght" 600, "slnt" 100 !important; font-weight:600 !important; font-style:oblique !important; }
|
||||
.font-style-bold { font-variation-settings: "wght" 700, "slnt" 0 !important; font-weight:700 !important; font-style:normal !important; }
|
||||
.font-style-bold-italic { font-variation-settings: "wght" 700, "slnt" 100 !important; font-weight:700 !important; font-style:oblique !important; }
|
||||
.font-style-extra-bold { font-variation-settings: "wght" 800, "slnt" 0 !important; font-weight:800 !important; font-style:normal !important; }
|
||||
.font-style-extra-bold-italic { font-variation-settings: "wght" 800, "slnt" 100 !important; font-weight:800 !important; font-style:oblique !important; }
|
||||
.font-style-black { font-variation-settings: "wght" 900, "slnt" 0 !important; font-weight:900 !important; font-style:normal !important; }
|
||||
.font-style-black-italic { font-variation-settings: "wght" 900, "slnt" 100 !important; font-weight:900 !important; font-style:oblique !important; }
|
||||
|
||||
@supports (font-variation-settings: normal) {
|
||||
body {
|
||||
font-family: 'Inter var', system-ui, sans-serif;
|
||||
}
|
||||
body.chrome-win {
|
||||
/* Chrome has some VF issues; worst are on Windows with incorrect kerning.
|
||||
We disable VF on Chrome on Windows for that reason.
|
||||
*/
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
DISABLED:target:before {
|
||||
content:"";
|
||||
display: block;
|
||||
height: 20px; /* fixed header height*/
|
||||
margin: -20px 0 0; /* negative fixed header height */
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline rgba(0, 0, 0, 0.3);
|
||||
color: black;
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a.fat {
|
||||
font-weight:500;
|
||||
color: #333;
|
||||
}
|
||||
a:hover {
|
||||
color: var(--red);
|
||||
text-decoration: underline;
|
||||
}
|
||||
a.plain, a.fat {
|
||||
background: none;
|
||||
text-shadow: none;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
a[href^="#"]:hover {
|
||||
text-decoration-style: dashed;
|
||||
}
|
||||
|
||||
/*p, pre {
|
||||
margin: 1rem 0;
|
||||
}*/
|
||||
code, pre, q, tt {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1, 'ss02' 1, 'zero' 1;
|
||||
line-height: inherit;
|
||||
}
|
||||
code {
|
||||
display: block;
|
||||
border-radius:1px;
|
||||
padding: 0.5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
line-break: loose;
|
||||
overflow-x: auto;
|
||||
}
|
||||
q {
|
||||
display: inline;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
q {
|
||||
display: inline;
|
||||
}
|
||||
q:before {
|
||||
content: "";
|
||||
}
|
||||
q:after {
|
||||
content: "";
|
||||
}
|
||||
kbd {
|
||||
-moz-font-feature-settings: 'liga' 1, 'calt' 1, 'kern' 1, 'case' 1;
|
||||
-ms-font-feature-settings: 'liga' 1, 'calt' 1, 'kern' 1, 'case' 1;
|
||||
-o-font-feature-settings: 'liga' 1, 'calt' 1, 'kern' 1, 'case' 1;
|
||||
-webkit-font-feature-settings: 'liga' 1, 'calt' 1, 'kern' 1, 'case' 1;
|
||||
font-feature-settings: 'liga' 1, 'calt' 1, 'kern' 1, 'case' 1;
|
||||
border: 1px solid rgba(0,0,0,0.18);
|
||||
border-radius: 3px;
|
||||
padding:0.1em 0.2em;
|
||||
margin:0 0.1em;
|
||||
}
|
||||
dem { /* de-emphasize */
|
||||
font-weight: 400;
|
||||
opacity: 0.7;
|
||||
}
|
||||
num { /* number */
|
||||
/*-moz-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-ms-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-o-font-feature-settings: 'calt' 1, 'ss01' 1;
|
||||
-webkit-font-feature-settings: 'kern' 1, 'calt' 1, 'ss01' 1;
|
||||
font-feature-settings: 'calt' 1, 'ss01' 1;*/
|
||||
letter-spacing:0.01em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
em, i, .italic {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.012em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
/*h1, .h1 {
|
||||
color: #222;
|
||||
font-size: 55px;
|
||||
letter-spacing: -0.038em;
|
||||
line-height: 1.1em;
|
||||
text-indent: -2px;
|
||||
font-weight: 700;
|
||||
}
|
||||
h1 {
|
||||
margin-bottom: 30px;
|
||||
margin-top: 10px;
|
||||
}*/
|
||||
h1, .h1 {
|
||||
margin-left: calc(3rem / -20);
|
||||
font-weight: 700;
|
||||
font-size: 4rem;
|
||||
letter-spacing: -0.07em;
|
||||
line-height: calc(var(--spacingv) * 6);
|
||||
}
|
||||
h1 {
|
||||
margin-bottom: calc(var(--spacingv) * 2);
|
||||
}
|
||||
|
||||
h2, .h2 {
|
||||
font-weight: 700;
|
||||
font-size: 1.8rem;
|
||||
letter-spacing: -0.03em;
|
||||
line-height: calc(var(--spacingv) * 3);
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: calc(var(--spacingv) * 2);
|
||||
}
|
||||
h3, .h3 {
|
||||
font-weight: 700;
|
||||
font-weight: 650;
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: -0.018em;
|
||||
line-height: calc(var(--spacingv) * 2);
|
||||
}
|
||||
h3 {
|
||||
margin-bottom: calc(var(--spacingv) * 2);
|
||||
}
|
||||
|
||||
h3 q, h3. q {
|
||||
font-weight: 400;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
h1 > a, h2 > a, h3 > a, h4 > a,
|
||||
.h1 > a, .h2 > a, .h3 > a, .h4 > a {
|
||||
display:block;
|
||||
color: inherit;
|
||||
text-decoration: none !important;
|
||||
text-shadow: none;
|
||||
background: none;
|
||||
outline:none;
|
||||
}
|
||||
|
||||
h4, h5, h6, .h4, .h5, .h6 {
|
||||
font-weight: 640;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
h4, h5, h6 {
|
||||
margin-bottom: calc(var(--spacingv) * 1);
|
||||
}
|
||||
/* add top margin to Hn when it follows another element */
|
||||
* + h1 { margin-top: calc(var(--spacingv) * 6); }
|
||||
* + h2 { margin-top: calc(var(--spacingv) * 4); }
|
||||
* + h3 { margin-top: calc(var(--spacingv) * 3); }
|
||||
* + h4 { margin-top: calc(var(--spacingv) * 2); }
|
||||
|
||||
p, pre, p + grid, pre + grid {
|
||||
margin-bottom: var(--lineHeight);
|
||||
}
|
||||
|
||||
|
||||
.row.dark h2,
|
||||
.row.black h2 {
|
||||
letter-spacing: -0.014em;
|
||||
}
|
||||
h2.back {
|
||||
color:rgba(0,0,0,0.2);
|
||||
font-size: inherit;
|
||||
letter-spacing: inherit;
|
||||
font-weight:400;
|
||||
margin:0;
|
||||
margin-top:-1.9em;
|
||||
}
|
||||
h2.back a:hover {
|
||||
color: black;
|
||||
margin-left:-1.3em;
|
||||
}
|
||||
h2.back a:hover::before {
|
||||
content: "<- ";
|
||||
}
|
||||
h2.banner {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
h2.banner > * {
|
||||
flex: 0 1 auto;
|
||||
padding: 0.8em 1.2em;
|
||||
border-radius: 4em;
|
||||
display: block;
|
||||
background: white;
|
||||
}
|
||||
h2.banner > a:hover {
|
||||
color: black;
|
||||
background: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.row.dark h3,
|
||||
.row.black h3 {
|
||||
letter-spacing: -0.012em;
|
||||
}
|
||||
|
||||
.row.yellow {
|
||||
background: var(--yellow);
|
||||
color: rgba(0, 0, 0, 0.98);
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.row > * {
|
||||
width:100%;
|
||||
max-width: 888px;
|
||||
flex: 1 0 100%;
|
||||
}
|
||||
.row .learn-more {
|
||||
margin-top: 2em;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.007em;
|
||||
}
|
||||
.row .learn-more a {
|
||||
color: rgba(0,0,0,0.4);
|
||||
text-decoration-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
.row .learn-more a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.row.full-width {
|
||||
padding: 50px 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.row.full-width > * {
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
.row-divider {
|
||||
height: 1rem;
|
||||
/*margin: 0 auto;
|
||||
max-width: 888px;
|
||||
height: 0.11rem;
|
||||
background: black;*/
|
||||
}
|
||||
|
||||
.row.menu {
|
||||
padding: 0;
|
||||
border-bottom:1px solid rgba(0,0,0,0.1);
|
||||
background: #111;
|
||||
color: white;
|
||||
border-top: 40px solid red;
|
||||
margin-top: -40px;
|
||||
}
|
||||
.row.menu ul {
|
||||
width: auto;
|
||||
max-width: 888px;
|
||||
flex: 1 1 auto;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 50px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.row.menu ul li {
|
||||
margin-bottom: -1px;
|
||||
text-indent: -0.5px;
|
||||
text-align: center;
|
||||
}
|
||||
.row.menu ul li > a {
|
||||
color: inherit;
|
||||
opacity: 0.8;
|
||||
text-decoration:none;
|
||||
display: inline-block;
|
||||
padding: 15px 20px 13px 20px;
|
||||
margin-right: 1px;
|
||||
font-weight: 450;
|
||||
/*transition: 80ms all cubic-bezier(0.25, 0.47, 0.44, 0.93);*/
|
||||
}
|
||||
.row.menu ul li > a:hover,
|
||||
.row.menu ul li > a.active {
|
||||
color: white;
|
||||
background: var(--red);
|
||||
opacity: 1;
|
||||
}
|
||||
.row.menu ul li:first-child > a {
|
||||
padding-left:0;
|
||||
padding-right:0;
|
||||
margin-right: 25px;
|
||||
background:transparent;
|
||||
}
|
||||
.row.menu ul li:first-child > a:hover {
|
||||
text-decoration:underline;
|
||||
}
|
||||
.row.menu ul li.nav-home > a {
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 565px) {
|
||||
.row {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
.row.menu ul {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4,1fr);
|
||||
margin: 0 20px;
|
||||
}
|
||||
.row.menu ul {
|
||||
}
|
||||
.row.menu ul li {
|
||||
display: flex;
|
||||
}
|
||||
.row.menu ul li > a {
|
||||
flex: 0 1 100%;
|
||||
margin: 0;
|
||||
padding-right:0;
|
||||
padding-left:0;
|
||||
box-shadow: inset 1px 0 0 0 rgba(255,255,255,0.1);
|
||||
}
|
||||
.row.menu ul li:first-child > a {
|
||||
margin-right: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
.row.menu ul li.nav-home a {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
/* progressively hide menu items */
|
||||
@media only screen and (max-width: 680px) {
|
||||
.row.menu .nav-lab { display: none; }
|
||||
}
|
||||
@media only screen and (max-width: 565px) {
|
||||
.row.menu .nav-download { display: none; }
|
||||
}
|
||||
@media only screen and (max-width: 280px) {
|
||||
.row.menu ul { grid-template-columns: repeat(3,1fr); }
|
||||
.row.menu .nav-dynmetrics { display: none; }
|
||||
}
|
||||
|
||||
|
||||
.row.white {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.row.dark,
|
||||
.row.black {
|
||||
background: #2b2b2b;
|
||||
color: #99999b;
|
||||
}
|
||||
.row.green {
|
||||
background: var(--mediumGreen);
|
||||
color: black;
|
||||
}
|
||||
.row.blue {
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
}
|
||||
.row.black {
|
||||
background: #010101;
|
||||
}
|
||||
.row.dark a,
|
||||
.row.black a {
|
||||
text-decoration-color: rgba(255, 255, 255, 0.2);
|
||||
color: #aaa;
|
||||
}
|
||||
.row.dark a:hover,
|
||||
.row.black a:hover {
|
||||
color: rgb(95, 170, 255);
|
||||
text-decoration: underline rgb(95, 170, 255);
|
||||
}
|
||||
.row.dark h2, .row.dark h2 > a,
|
||||
.row.black h2, .row.black h2 > a {
|
||||
color: #ccc;
|
||||
background: none;
|
||||
}
|
||||
.row.green h2 > a:hover {
|
||||
color: inherit;
|
||||
text-decoration-style: solid !important;
|
||||
text-decoration: underline !important;
|
||||
text-decoration: underline rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
.row.green > * > p > a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.row.color1 {
|
||||
background: #C0CDE2;
|
||||
color: #3B414A;
|
||||
}
|
||||
|
||||
.noise-layer {
|
||||
background-image: url(noise512.png);
|
||||
background-size: 256px;
|
||||
opacity: 0.03;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
/*bottom:0;*/
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ul { margin-left:1.1em; }
|
||||
a > img { display: block; }
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* generic helpers */
|
||||
|
||||
.low-contrast { opacity: 0.4; }
|
||||
.center-text { text-align: center; }
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#repertoire-image {
|
||||
display:block;
|
||||
width:100%;
|
||||
height:40vw;
|
||||
background-image: url(r/repertoire.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-blend-mode: multiply;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.sample-images {}
|
||||
.sample-images img, .sample-images svg {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* grid */
|
||||
|
||||
grid {
|
||||
grid-column-gap: var(--columnGap);
|
||||
grid-row-gap: 0;
|
||||
}
|
||||
grid > c.spacer {
|
||||
grid-column: 1 / -1;
|
||||
height: calc(var(--spacingv) * 6);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 565px) {
|
||||
grid { grid-column-gap: 1rem; }
|
||||
grid > c.spacer { height: calc(var(--spacingv) * 3); }
|
||||
}
|
||||
|
||||
.row.features { display:none; }
|
||||
@supports (display: grid) {
|
||||
.row.features { display:flex; }
|
||||
}
|
||||
.row.features p.example { margin-top:2rem; opacity:0.4; }
|
||||
|
||||
.row.features grid {
|
||||
grid-column-gap: 1rem;
|
||||
grid-row-gap: 0.5rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* flow */
|
||||
|
||||
flow { display:block; appearance: none; -webkit-appearance: none }
|
||||
flow[columns] {
|
||||
column-gap: var(--columnGap);
|
||||
column-fill: balance;
|
||||
}
|
||||
flow[columns="2"] {
|
||||
column-count: 2;
|
||||
}
|
||||
@media only screen and (max-width: 565px) {
|
||||
flow[columns-s="1"] {
|
||||
column-count: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* column flow */
|
||||
[flow-cols], [flow-cols-s], [flow-cols-l] {
|
||||
column-gap: var(--columnGap);
|
||||
column-fill: balance;
|
||||
}
|
||||
[flow-cols="1"] { column-count: 1 }
|
||||
[flow-cols="2"] { column-count: 2 }
|
||||
[flow-cols="3"] { column-count: 3 }
|
||||
[flow-cols="4"] { column-count: 4 }
|
||||
[flow-cols="5"] { column-count: 5 }
|
||||
[flow-cols="6"] { column-count: 6 }
|
||||
[flow-cols="7"] { column-count: 7 }
|
||||
[flow-cols="8"] { column-count: 8 }
|
||||
|
||||
@media only screen and (max-width: 565px) {
|
||||
[flow-cols-s="1"] { column-count: 1 }
|
||||
[flow-cols-s="2"] { column-count: 2 }
|
||||
[flow-cols-s="3"] { column-count: 3 }
|
||||
[flow-cols-s="4"] { column-count: 4 }
|
||||
[flow-cols-s="5"] { column-count: 5 }
|
||||
[flow-cols-s="6"] { column-count: 6 }
|
||||
[flow-cols-s="7"] { column-count: 7 }
|
||||
[flow-cols-s="8"] { column-count: 8 }
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
boxes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: stretch;
|
||||
margin-right:-1em;
|
||||
}
|
||||
box {
|
||||
overflow: auto;
|
||||
flex: 1 1 0;
|
||||
box-sizing: border-box;
|
||||
min-width: 270px;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: white;
|
||||
padding: 2em;
|
||||
border-radius: 3px;
|
||||
margin-right:1em;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
body.safari box {
|
||||
/* Fix for broken flex wrap in safari */
|
||||
flex-basis: 40%;
|
||||
}
|
||||
box:first-child {
|
||||
margin-left:0;
|
||||
}
|
||||
box h3 {
|
||||
margin-bottom:0.8em;
|
||||
}
|
||||
|
||||
box.large tablex r {
|
||||
line-height: 1.5;
|
||||
}
|
||||
box.large tablex r in,
|
||||
box.large tablex r to,
|
||||
box.large tablex r out {
|
||||
font-size: 2rem;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
#hud-notification {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
z-index: 9;
|
||||
pointer-events: none;
|
||||
}
|
||||
#hud-notification .msg {
|
||||
background: #000;
|
||||
color: white;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0em;
|
||||
padding: 0 0.7em;
|
||||
border-radius: 4px;
|
||||
opacity: 0.1;
|
||||
transition: 250ms all ease-in;
|
||||
transform: translate3d(0, 71px, 0); /* height + bottom offset + 1 */
|
||||
}
|
||||
#hud-notification.visible .msg {
|
||||
transform: translate3d(0, 0, 0);
|
||||
transition: 120ms all cubic-bezier(0.25, 0.47, 0.44, 0.93);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
|
||||
/* wide windows */
|
||||
@media only screen and (min-width: 566px) {
|
||||
.narrow-window, .only-small-screen { display: none; }
|
||||
}
|
||||
|
||||
/* narrow windows */
|
||||
@media only screen and (max-width: 565px) {
|
||||
.wide-window, .only-large-screen { display: none; }
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 6+) */
|
||||
@media only screen and (max-device-width: 414px) {
|
||||
box { padding: 1em; }
|
||||
box tablex r { font-size: 0.9em; }
|
||||
body {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.row {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* small devices (<= iPhone 5) */
|
||||
@media only screen and (max-device-width: 320px) {
|
||||
box {
|
||||
font-size: 0.8em;
|
||||
min-width: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Feature helpers.
|
||||
|
||||
Note: font-variant-alternates:character-variant is not yet supported by
|
||||
most browsers, which is why we use the "low leve" font-feature-settings
|
||||
instead.
|
||||
|
||||
*/
|
||||
|
||||
.ff-none { font-feature-settings: 'kern' 1, 'calt' 0, 'liga' 0; -webkit-font-feature-settings: 'kern' 1, 'calt' 0, 'liga' 0; -ms-font-feature-settings: 'kern' 1, 'calt' 0, 'liga' 0; -moz-font-feature-settings: 'kern' 1, 'calt' 0, 'liga' 0; }
|
||||
|
||||
.ff-liga,
|
||||
.ff-calt { font-feature-settings: 'liga' 1, 'calt' 1; -webkit-font-feature-settings: 'liga' 1, 'calt' 1; -ms-font-feature-settings: 'liga' 1, 'calt' 1; -moz-font-feature-settings: 'liga' 1, 'calt' 1; }
|
||||
.ff-dlig { font-feature-settings: 'kern' 1, 'dlig' 1; -webkit-font-feature-settings: 'kern' 1, 'dlig' 1; -ms-font-feature-settings: 'kern' 1, 'dlig' 1; -moz-font-feature-settings: 'kern' 1, 'dlig' 1; }
|
||||
.ff-numr { font-feature-settings: 'kern' 1, 'numr' 1; -webkit-font-feature-settings: 'kern' 1, 'numr' 1; -ms-font-feature-settings: 'kern' 1, 'numr' 1; -moz-font-feature-settings: 'kern' 1, 'numr' 1; }
|
||||
.ff-dnom { font-feature-settings: 'kern' 1, 'dnom' 1; -webkit-font-feature-settings: 'kern' 1, 'dnom' 1; -ms-font-feature-settings: 'kern' 1, 'dnom' 1; -moz-font-feature-settings: 'kern' 1, 'dnom' 1; }
|
||||
.ff-tnum { font-feature-settings: 'kern' 1, 'tnum' 1; -webkit-font-feature-settings: 'kern' 1, 'tnum' 1; -ms-font-feature-settings: 'kern' 1, 'tnum' 1; -moz-font-feature-settings: 'kern' 1, 'tnum' 1; }
|
||||
.ff-case { font-feature-settings: 'kern' 1, 'case' 1; -webkit-font-feature-settings: 'kern' 1, 'case' 1; -ms-font-feature-settings: 'kern' 1, 'case' 1; -moz-font-feature-settings: 'kern' 1, 'case' 1; }
|
||||
.ff-zero { font-feature-settings: 'kern' 1, 'zero' 1; -webkit-font-feature-settings: 'kern' 1, 'zero' 1; -ms-font-feature-settings: 'kern' 1, 'zero' 1; -moz-font-feature-settings: 'kern' 1, 'zero' 1; }
|
||||
.ff-frac { font-feature-settings: 'kern' 1, 'frac' 1; -webkit-font-feature-settings: 'kern' 1, 'frac' 1; -ms-font-feature-settings: 'kern' 1, 'frac' 1; -moz-font-feature-settings: 'kern' 1, 'frac' 1; }
|
||||
.ff-sups { font-feature-settings: 'kern' 1, 'sups' 1; -webkit-font-feature-settings: 'kern' 1, 'sups' 1; -ms-font-feature-settings: 'kern' 1, 'sups' 1; -moz-font-feature-settings: 'kern' 1, 'sups' 1; }
|
||||
.ff-subs { font-feature-settings: 'kern' 1, 'subs' 1; -webkit-font-feature-settings: 'kern' 1, 'subs' 1; -ms-font-feature-settings: 'kern' 1, 'subs' 1; -moz-font-feature-settings: 'kern' 1, 'subs' 1; }
|
||||
.ff-cpsp { font-feature-settings: 'kern' 1, 'cpsp' 1; -webkit-font-feature-settings: 'kern' 1, 'cpsp' 1; -ms-font-feature-settings: 'kern' 1, 'cpsp' 1; -moz-font-feature-settings: 'kern' 1, 'cpsp' 1; }
|
||||
.ff-salt { font-feature-settings: 'kern' 1, 'salt' 1; -webkit-font-feature-settings: 'kern' 1, 'salt' 1; -ms-font-feature-settings: 'kern' 1, 'salt' 1; -moz-font-feature-settings: 'kern' 1, 'salt' 1; }
|
||||
.ff-salt-zero { font-feature-settings: 'kern' 1, 'salt' 1, 'zero' 1; }
|
||||
.ff-cv07-salt-zero { font-feature-settings: 'kern' 1, 'cv07' 1, 'salt' 1, 'zero' 1; }
|
||||
|
||||
.ff-ss01 { font-feature-settings: 'kern' 1, 'ss01' 1; -webkit-font-feature-settings: 'kern' 1, 'ss01' 1; -ms-font-feature-settings: 'kern' 1, 'ss01' 1; -moz-font-feature-settings: 'kern' 1, 'ss01' 1; }
|
||||
.ff-ss02 { font-feature-settings: 'kern' 1, 'ss02' 1; -webkit-font-feature-settings: 'kern' 1, 'ss02' 1; -ms-font-feature-settings: 'kern' 1, 'ss02' 1; -moz-font-feature-settings: 'kern' 1, 'ss02' 1; }
|
||||
.ff-ss03 { font-feature-settings: 'kern' 1, 'ss03' 1; -webkit-font-feature-settings: 'kern' 1, 'ss03' 1; -ms-font-feature-settings: 'kern' 1, 'ss03' 1; -moz-font-feature-settings: 'kern' 1, 'ss03' 1; }
|
||||
.ff-cv01 { font-feature-settings: 'kern' 1, 'cv01' 1; -webkit-font-feature-settings: 'kern' 1, 'cv01' 1; -ms-font-feature-settings: 'kern' 1, 'cv01' 1; -moz-font-feature-settings: 'kern' 1, 'cv01' 1; }
|
||||
.ff-cv02 { font-feature-settings: 'kern' 1, 'cv02' 1; -webkit-font-feature-settings: 'kern' 1, 'cv02' 1; -ms-font-feature-settings: 'kern' 1, 'cv02' 1; -moz-font-feature-settings: 'kern' 1, 'cv02' 1; }
|
||||
.ff-cv03 { font-feature-settings: 'kern' 1, 'cv03' 1; -webkit-font-feature-settings: 'kern' 1, 'cv03' 1; -ms-font-feature-settings: 'kern' 1, 'cv03' 1; -moz-font-feature-settings: 'kern' 1, 'cv03' 1; }
|
||||
.ff-cv04 { font-feature-settings: 'kern' 1, 'cv04' 1; -webkit-font-feature-settings: 'kern' 1, 'cv04' 1; -ms-font-feature-settings: 'kern' 1, 'cv04' 1; -moz-font-feature-settings: 'kern' 1, 'cv04' 1; }
|
||||
.ff-cv05 { font-feature-settings: 'kern' 1, 'cv05' 1; -webkit-font-feature-settings: 'kern' 1, 'cv05' 1; -ms-font-feature-settings: 'kern' 1, 'cv05' 1; -moz-font-feature-settings: 'kern' 1, 'cv05' 1; }
|
||||
.ff-cv06 { font-feature-settings: 'kern' 1, 'cv06' 1; -webkit-font-feature-settings: 'kern' 1, 'cv06' 1; -ms-font-feature-settings: 'kern' 1, 'cv06' 1; -moz-font-feature-settings: 'kern' 1, 'cv06' 1; }
|
||||
.ff-cv07 { font-feature-settings: 'kern' 1, 'cv07' 1; -webkit-font-feature-settings: 'kern' 1, 'cv07' 1; -ms-font-feature-settings: 'kern' 1, 'cv07' 1; -moz-font-feature-settings: 'kern' 1, 'cv07' 1; }
|
||||
.ff-cv08 { font-feature-settings: 'kern' 1, 'cv08' 1; -webkit-font-feature-settings: 'kern' 1, 'cv08' 1; -ms-font-feature-settings: 'kern' 1, 'cv08' 1; -moz-font-feature-settings: 'kern' 1, 'cv08' 1; }
|
||||
.ff-cv09 { font-feature-settings: 'kern' 1, 'cv09' 1; -webkit-font-feature-settings: 'kern' 1, 'cv09' 1; -ms-font-feature-settings: 'kern' 1, 'cv09' 1; -moz-font-feature-settings: 'kern' 1, 'cv09' 1; }
|
||||
.ff-cv10 { font-feature-settings: 'kern' 1, 'cv10' 1; -webkit-font-feature-settings: 'kern' 1, 'cv10' 1; -ms-font-feature-settings: 'kern' 1, 'cv10' 1; -moz-font-feature-settings: 'kern' 1, 'cv10' 1; }
|
||||
.ff-cv11 { font-feature-settings: 'kern' 1, 'cv11' 1; -webkit-font-feature-settings: 'kern' 1, 'cv11' 1; -ms-font-feature-settings: 'kern' 1, 'cv11' 1; -moz-font-feature-settings: 'kern' 1, 'cv11' 1; }
|
||||
|
||||
|
||||
|
||||
.row.charset {
|
||||
padding-top: 1rem;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
/* maintain cascading margin-bottom */
|
||||
}
|
||||
|
||||
.charset-table {
|
||||
--gridColor: #bbb;
|
||||
--columns: 24;
|
||||
--columnsL: 32;
|
||||
--columnsS: 16;
|
||||
--columnsXS: 8;
|
||||
--tableWidth: 95vw;
|
||||
|
||||
flex: 1 1 auto;
|
||||
padding: 0;
|
||||
margin: 1rem auto;
|
||||
|
||||
max-width: var(--tableWidth);
|
||||
width: var(--tableWidth);
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
box-shadow: -1px -1px 0 var(--gridColor),
|
||||
-1px 0 0 var(--gridColor),
|
||||
0 -1px 0 var(--gridColor);
|
||||
}
|
||||
.charset-table > a {
|
||||
flex: 0 0 auto;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: calc(var(--tableWidth) / var(--columns));
|
||||
height: calc(var(--tableWidth) / var(--columns));
|
||||
|
||||
font-size: calc(100vw / calc(var(--columns) * 2));
|
||||
line-height: 100%;
|
||||
text-align: center;
|
||||
font-feature-settings: "calt" 0; /* disable all */
|
||||
|
||||
box-shadow: inset -1px -1px 0 var(--gridColor);
|
||||
text-decoration: none;
|
||||
}
|
||||
/* for window width >= 1600 */
|
||||
@media only screen and (min-width: 1599px) {
|
||||
.charset-table { --columns: var(--columnsL); }
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
.charset-table { --columns: var(--columnsS); }
|
||||
}
|
||||
@media only screen and (max-width: 565px) {
|
||||
.charset-table { --columns: var(--columnsXS); }
|
||||
}
|
115
docs/r/base.js
Normal file
@ -0,0 +1,115 @@
|
||||
|
||||
function $$(query, el) {
|
||||
return [].slice.call((el || document).querySelectorAll(query))
|
||||
}
|
||||
|
||||
function $(query, el) {
|
||||
return (el || document).querySelector(query)
|
||||
}
|
||||
|
||||
// fetchjson(url string) :Promise<Object>
|
||||
//
|
||||
var fetchjson = (
|
||||
typeof window.fetch == 'function' ? (
|
||||
function _fetchjson(url, cb) {
|
||||
return window.fetch(url).then(function(r) { return r.json() })
|
||||
}
|
||||
) :
|
||||
function _fetchjson(url, cb) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var r = new XMLHttpRequest()
|
||||
r.addEventListener("load", function(){
|
||||
try {
|
||||
resolve(JSON.parse(r.responseText))
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
r.addEventListener("error", function(ev) {
|
||||
reject(ev.error || ev || new Error('network error'))
|
||||
})
|
||||
r.open("GET", url)
|
||||
r.send()
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// timeNow() :float
|
||||
//
|
||||
var timeNow = (
|
||||
window.performance !== undefined && window.performance.now ? function() {
|
||||
return window.performance.now()
|
||||
} : Date.now ? function() {
|
||||
return Date.now()
|
||||
} : function() {
|
||||
return (new Date()).getTime()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
var HUDNotification = {
|
||||
el: $('#hud-notification'),
|
||||
timer: null,
|
||||
visible: false,
|
||||
|
||||
show: function(message, duration) {
|
||||
var n = this
|
||||
n.el.firstChild.innerText = message
|
||||
n.el.classList.add('visible')
|
||||
if (n.visible) {
|
||||
n.hide()
|
||||
setTimeout(function(){ n.show(message, duration) }, 120)
|
||||
return
|
||||
}
|
||||
n.visible = true
|
||||
n.el.style.visibility = null
|
||||
clearTimeout(n.timer)
|
||||
n.timer = setTimeout(function(){ n.hide() }, duration || 1200)
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
var n = this
|
||||
if (n.visible) {
|
||||
n.el.classList.remove('visible')
|
||||
n.visible = false
|
||||
n.el.style.visibility = 'hidden'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// InterDynamicTracking takes the font size in points or pixels and returns
|
||||
// the compensating tracking in EM.
|
||||
//
|
||||
function InterDynamicTracking(fontSize) {
|
||||
var a = -0.0223, b = 0.185, c = -0.1745;
|
||||
// tracking = a + b * e ^ (c * fontSize)
|
||||
return a + b * Math.pow(Math.E, c * fontSize)
|
||||
}
|
||||
|
||||
// InterDynamicLineHeight produces the line height for the given font size
|
||||
//
|
||||
function InterDynamicLineHeight(fontSize) {
|
||||
var l = 1.4
|
||||
return Math.round(fontSize * l)
|
||||
}
|
||||
|
||||
|
||||
// Mac or not? Maybe a buggy Safari or a busted Chrome on Windows...
|
||||
var isMac = false
|
||||
if (!window.MSStream &&
|
||||
/mac|ipad|iphone|ipod/i.test(navigator.userAgent))
|
||||
{
|
||||
isMac = true
|
||||
if (navigator.userAgent.indexOf('Safari') != -1 &&
|
||||
navigator.userAgent.indexOf('Chrome') == -1)
|
||||
{
|
||||
document.body.classList.add('safari')
|
||||
}
|
||||
} else if (
|
||||
navigator.userAgent.indexOf('Windows') != -1 &&
|
||||
navigator.userAgent.indexOf('Chrome') != -1
|
||||
) {
|
||||
document.body.classList.add('chrome-win')
|
||||
}
|
242
docs/r/bindings.js
Normal file
@ -0,0 +1,242 @@
|
||||
// requires index.js
|
||||
|
||||
function passThrough(v) { return v }
|
||||
|
||||
function valueGetter(el) {
|
||||
return (
|
||||
'valueAsNumber' in el ? () => el.valueAsNumber :
|
||||
(el.type == 'number' || el.type == 'range') ? () => parseFloat(el.value) :
|
||||
() => el.value
|
||||
)
|
||||
}
|
||||
|
||||
function Binding(name){
|
||||
this.name = name
|
||||
this.value = undefined
|
||||
this.inputs = []
|
||||
this.outputs = []
|
||||
this.listeners = []
|
||||
this.parser = undefined
|
||||
this.formatter = passThrough
|
||||
}
|
||||
|
||||
|
||||
Binding.prototype.addInput = function(el) {
|
||||
var binding = this
|
||||
var getValue = valueGetter(el)
|
||||
var _onInput = ev => {
|
||||
binding.setValue(getValue(), el)
|
||||
}
|
||||
var input = {
|
||||
el: el,
|
||||
_onInput: _onInput,
|
||||
}
|
||||
this.inputs.push(input)
|
||||
if (this.value === undefined) {
|
||||
this.value = getValue()
|
||||
} else {
|
||||
input.el.value = this.formatter(this.value)
|
||||
}
|
||||
if (el.tagName == 'SELECT' || el.type == 'checkbox') {
|
||||
el.addEventListener('change', _onInput, {passive:true})
|
||||
} else {
|
||||
el.addEventListener('input', _onInput, {passive:true})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binding.prototype.addOutput = function(el) {
|
||||
this.outputs.push(el)
|
||||
if (this.value !== undefined) {
|
||||
el.innerText = this.formatter(this.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// listener signature:
|
||||
// function(nextval string, prevval string, b Binding)void
|
||||
//
|
||||
Binding.prototype.addListener = function(listener) {
|
||||
this.listeners.push(listener)
|
||||
}
|
||||
|
||||
|
||||
Binding.prototype.setValue = function(nextval, origin) {
|
||||
var prevval = this.value
|
||||
if (this.parser) {
|
||||
nextval = this.parser(nextval, prevval)
|
||||
}
|
||||
if (this.value === nextval) {
|
||||
return
|
||||
}
|
||||
var binding = this
|
||||
this.value = nextval
|
||||
var value = binding.formatter(nextval)
|
||||
this.inputs.forEach(function(input) {
|
||||
if (input.el !== origin) {
|
||||
input.el.value = value
|
||||
}
|
||||
})
|
||||
this.outputs.forEach(function(el) {
|
||||
el.innerText = value
|
||||
})
|
||||
this.listeners.forEach(function(listener) {
|
||||
listener(nextval, prevval, this)
|
||||
})
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
function Bindings() {
|
||||
this.bindings = {}
|
||||
}
|
||||
|
||||
Bindings.prototype.getBinding = function(name) {
|
||||
var binding = this.bindings[name]
|
||||
if (!binding) {
|
||||
binding = new Binding(name)
|
||||
this.bindings[name] = binding
|
||||
}
|
||||
return binding
|
||||
}
|
||||
|
||||
Bindings.prototype.bindInput = function(name, input) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.addInput(input)
|
||||
}
|
||||
|
||||
Bindings.prototype.bindOutput = function(name, el) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.addOutput(el)
|
||||
}
|
||||
|
||||
Bindings.prototype.bindAllInputs = function(queryOrInputElementList) {
|
||||
var bindings = this
|
||||
|
||||
var elements = (
|
||||
typeof queryOrInputElementList == 'string' ? $$(queryOrInputElementList) :
|
||||
queryOrInputElementList
|
||||
)
|
||||
|
||||
elements.forEach(function(el) {
|
||||
var bindingName = el.dataset.binding
|
||||
if (bindingName) {
|
||||
if (
|
||||
el.tagName == 'INPUT' ||
|
||||
el.tagName == 'TEXTAREA' ||
|
||||
el.tagName == 'SELECT'
|
||||
) {
|
||||
bindings.bindInput(bindingName, el)
|
||||
} else {
|
||||
bindings.bindOutput(bindingName, el)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// listener signature:
|
||||
// function(nextval string, prevval string, b Binding)void
|
||||
//
|
||||
Bindings.prototype.addListener = function(name, listener) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.addListener(listener)
|
||||
}
|
||||
|
||||
Bindings.prototype.setValue = function(name, value) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.setValue(value)
|
||||
}
|
||||
|
||||
Bindings.prototype.setFormatter = function(name, formatter) {
|
||||
var binding = this.getBinding(name)
|
||||
binding.formatter = formatter || passThrough
|
||||
}
|
||||
|
||||
|
||||
Bindings.prototype.value = function(name, defaultValue) {
|
||||
var binding = this.bindings[name]
|
||||
return binding && binding.value !== undefined ? binding.value : defaultValue
|
||||
}
|
||||
|
||||
|
||||
function fmt_float(nextval, prevval) {
|
||||
var n = parseFloat(nextval)
|
||||
return isNaN(n) ? 0 : n
|
||||
}
|
||||
|
||||
function fmt_int(nextval, prevval) {
|
||||
var n = parseInt(nextval)
|
||||
return isNaN(n) ? 0 : n
|
||||
}
|
||||
|
||||
|
||||
// configure is convenience function for setting value, adding a
|
||||
// listener and associating a parser with a binding.
|
||||
// If a listener and a value is provided, the value is set and the listener
|
||||
// is immediately invoked.
|
||||
//
|
||||
Bindings.prototype.configure = function(name, value, parser, listener) {
|
||||
var binding = this.getBinding(name)
|
||||
if (listener) {
|
||||
binding.addListener(listener)
|
||||
}
|
||||
if (value !== undefined && value !== null) {
|
||||
binding.setValue(value)
|
||||
}
|
||||
if (parser) {
|
||||
if (typeof parser == 'string') {
|
||||
switch (parser) {
|
||||
case 'number':
|
||||
case 'float':
|
||||
parser = fmt_float; break;
|
||||
|
||||
case 'int':
|
||||
case 'integer':
|
||||
parser = fmt_int; break;
|
||||
|
||||
default:
|
||||
throw new Error('unknown parser "' + parser + '"')
|
||||
}
|
||||
} else if (typeof parser != 'function') {
|
||||
throw new Error('parser should be a string or function')
|
||||
}
|
||||
binding.parser = parser
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bindings.prototype.allBindings = (
|
||||
typeof Object.values == 'function' ? function() {
|
||||
return Object.values(this.bindings)
|
||||
} : function() {
|
||||
let v = []
|
||||
for (let name in this.bindings) {
|
||||
v.push(this.bindings[name])
|
||||
}
|
||||
return v
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Bindings.prototype.getValues = function() {
|
||||
let values = {}
|
||||
for (let name in this.bindings) {
|
||||
values[name] = this.bindings[name].value
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
|
||||
Bindings.prototype.setValues = function(values) {
|
||||
Object.keys(values).forEach(name => {
|
||||
let b = this.bindings[name]
|
||||
if (!b) {
|
||||
if (console.warn) {
|
||||
console.warn('Bindings.setValues: ignoring unknown "' + name + '"')
|
||||
}
|
||||
return
|
||||
}
|
||||
// console.log(`bindings setValue ${name} => ${values[name]}`)
|
||||
b.setValue(values[name])
|
||||
})
|
||||
}
|
1
docs/r/close.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 8.707l4.646 4.647.708-.708L8.707 8l4.647-4.646-.708-.708L8 7.293 3.354 2.646l-.708.708L7.293 8l-4.647 4.646.708.708L8 8.707z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 232 B |
337
docs/r/ctxedit.css
Normal file
@ -0,0 +1,337 @@
|
||||
:root {
|
||||
--strip-height: 40px;
|
||||
}
|
||||
|
||||
#ctxedit-ui {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 0;
|
||||
height: var(--strip-height);
|
||||
|
||||
background: #111;
|
||||
color: #ccc;
|
||||
font-size: 12px;
|
||||
/*border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;*/
|
||||
|
||||
padding: 0 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
opacity:0;
|
||||
transition: 90ms all cubic-bezier(0.25, 0.47, 0.44, 0.93);
|
||||
transform: translate(0, var(--strip-height));
|
||||
|
||||
outline: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
#ctxedit-ui.visible {
|
||||
opacity:1;
|
||||
transform: translate(0, 0);
|
||||
pointer-events: initial;
|
||||
}
|
||||
#ctxedit-ui .wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 888px; /* same as base.css .row > * */
|
||||
flex: 1 0 100%;
|
||||
}
|
||||
#ctxedit-ui .control {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
min-height: 30px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
#ctxedit-ui .control:first-child {
|
||||
margin-left:0;
|
||||
}
|
||||
#ctxedit-ui .control.range {
|
||||
flex: 1 1 auto;
|
||||
max-width: 200px;
|
||||
}
|
||||
#ctxedit-ui .control > * {
|
||||
flex: 1 1 auto;
|
||||
margin:0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#ctxedit-ui .control > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
#ctxedit-ui .control > select {
|
||||
min-width: 8em;
|
||||
flex: 0 1 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
#ctxedit-ui .control > input,
|
||||
#ctxedit-ui .control > select {
|
||||
width: 0;
|
||||
outline: none;
|
||||
color: inherit;
|
||||
}
|
||||
#ctxedit-ui .control.popup {
|
||||
margin-right: 0px;
|
||||
}
|
||||
#ctxedit-ui .control > select {
|
||||
font: inherit;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
background-color: #111;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: var(--strip-height);
|
||||
background-image: url(popup.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
width: 120px;
|
||||
color: white;
|
||||
opacity: 0.6;
|
||||
padding-left: 20px;
|
||||
line-height: var(--strip-height);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
#ctxedit-ui .control > select::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
#ctxedit-ui .control > select:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 #fff;
|
||||
background-color: #111;
|
||||
font: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
#ctxedit-ui .control > select:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
#ctxedit-ui .control > input[type="number"],
|
||||
#ctxedit-ui .control > input[type="text"] {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px 0;
|
||||
font-size: inherit;
|
||||
/*border-radius: 2px;*/
|
||||
}
|
||||
#ctxedit-ui .control > input[type="number"] {
|
||||
max-width: 48px;
|
||||
text-align: left;
|
||||
-moz-appearance: textfield;
|
||||
-moz-font-feature-settings: 'tnum' 1;
|
||||
-ms-font-feature-settings: 'tnum' 1;
|
||||
-o-font-feature-settings: 'tnum' 1;
|
||||
-webkit-font-feature-settings: 'tnum' 1;
|
||||
font-feature-settings: 'tnum' 1;
|
||||
}
|
||||
#ctxedit-ui .control > input[type=number]::-webkit-inner-spin-button,
|
||||
#ctxedit-ui .control > input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
#ctxedit-ui .control > input[type="range"] {
|
||||
/*max-width: 80%;*/
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
}
|
||||
#ctxedit-ui .control > input[type="color"] {
|
||||
width:20px;
|
||||
height:20px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
#ctxedit-ui .control > img.icon,
|
||||
#ctxedit-ui .control > label {
|
||||
user-select: none;
|
||||
font-family: georgia, serif;
|
||||
font-style: italic;
|
||||
color: white;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
#ctxedit-ui .button {
|
||||
width: var(--strip-height);
|
||||
height: var(--strip-height);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.6;
|
||||
margin:0;
|
||||
}
|
||||
#ctxedit-ui .button:hover {
|
||||
opacity: 1;
|
||||
background-color: #292929;
|
||||
}
|
||||
#ctxedit-ui .button:active {
|
||||
background-color: #444;
|
||||
}
|
||||
#ctxedit-ui .button.features-button { background-image: url(settings.svg); }
|
||||
#ctxedit-ui .button.reset-button { background-image: url(reset.svg); }
|
||||
#ctxedit-ui .button.dismiss-button { background-image: url(dismiss.svg); }
|
||||
|
||||
|
||||
|
||||
/* narrow viewports */
|
||||
@media only screen and (max-width: 639px) {
|
||||
#ctxedit-ui {
|
||||
background: black;
|
||||
height: calc(var(--strip-height) * 4);
|
||||
}
|
||||
#ctxedit-ui .wrapper {
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.font-preload {
|
||||
position: fixed;
|
||||
display: block;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.slider-value-tip {
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
/*background: hotpink;*/
|
||||
left: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 9;
|
||||
transition: opacity 120ms ease-out;
|
||||
filter: drop-shadow(0px 2px 6px rgba(0,0,0,0.2));
|
||||
--fgcolor: #fff;
|
||||
--bgcolor: #444;
|
||||
}
|
||||
.slider-value-tip .value {
|
||||
padding: 4px 10px;
|
||||
border-radius: 2px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.013em;
|
||||
color: var(--fgcolor);
|
||||
background: var(--bgcolor);
|
||||
-moz-font-feature-settings: 'tnum' 1;
|
||||
-ms-font-feature-settings: 'tnum' 1;
|
||||
-o-font-feature-settings: 'tnum' 1;
|
||||
-webkit-font-feature-settings: 'tnum' 1;
|
||||
font-feature-settings: 'tnum' 1;
|
||||
z-index: 1;
|
||||
}
|
||||
.slider-value-tip .callout {
|
||||
background: var(--bgcolor);
|
||||
width:10px;
|
||||
height:10px;
|
||||
transform: translate(0, -6px) rotate(45deg);
|
||||
z-index: 0;
|
||||
}
|
||||
.slider-value-tip.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.styled-inputs-neg {
|
||||
--track-thickness: 2px;
|
||||
--track-color: rgba(255, 255, 255, 0.3);
|
||||
|
||||
--thumb-outline-thickness: 2px;
|
||||
--thumb-outline-color: #111; /* match control strip */
|
||||
--thumb-diameter: 10px;
|
||||
--thumb-color: white;
|
||||
|
||||
--active-color: rgb(95, 170, 255);
|
||||
}
|
||||
|
||||
.styled-inputs-neg input[type=range] {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: var(--strip-height);
|
||||
background: transparent;
|
||||
}
|
||||
.styled-inputs-neg input[type=range]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.styled-inputs-neg input[type=range]::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
animate: 0.2s;
|
||||
background: var(--track-color);
|
||||
height: var(--track-thickness);
|
||||
}
|
||||
.styled-inputs-neg input[type=range]:focus::-webkit-slider-runnable-track {
|
||||
background: var(--active-color);
|
||||
}
|
||||
.styled-inputs-neg input[type=range]::-moz-range-track {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
animate: 0.2s;
|
||||
background: var(--track-color);
|
||||
height: var(--track-thickness);
|
||||
}
|
||||
.styled-inputs-neg input[type=range]:focus::-moz-range-track {
|
||||
background: var(--active-color);
|
||||
}
|
||||
|
||||
.styled-inputs-neg input[type=range]::-webkit-slider-thumb {
|
||||
--thumb-diameter2: calc(var(--thumb-diameter) + var(--thumb-outline-thickness) * 2);
|
||||
width: var(--thumb-diameter2);
|
||||
height: var(--thumb-diameter2);
|
||||
border: var(--thumb-outline-thickness) solid var(--thumb-outline-color);
|
||||
border-radius: 100%;
|
||||
background: var(--thumb-color);
|
||||
-webkit-appearance: none;
|
||||
margin-top: calc(((var(--thumb-diameter2) / 2) - (var(--track-thickness) / 2)) * -1);
|
||||
}
|
||||
.styled-inputs-neg input[type=range]::-moz-range-thumb {
|
||||
width: var(--thumb-diameter);
|
||||
height: var(--thumb-diameter);
|
||||
border: var(--thumb-outline-thickness) solid var(--thumb-outline-color);
|
||||
border-radius: 100%;
|
||||
background: var(--thumb-color);
|
||||
margin-top: calc(((var(--thumb-diameter) / 2) - (var(--track-thickness) / 2)) * -1);
|
||||
}
|
||||
|
||||
/* MS Edge -- note that we can't use CSS variables here */
|
||||
.styled-inputs-neg input[type=range]::-ms-track {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
border-width: 0 0;
|
||||
color: transparent; /* markings */
|
||||
height: 2px;
|
||||
animate: 0.2s;
|
||||
margin: 0;
|
||||
}
|
||||
.styled-inputs-neg input[type=range]::-ms-fill-lower,
|
||||
.styled-inputs-neg input[type=range]::-ms-fill-upper {
|
||||
background: white;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.styled-inputs-neg input[type=range]::-ms-thumb {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
/*border: 2px solid rgba(0,0,0,0.8);*/
|
||||
box-shadow: 0px 0px 0px 2px #111;
|
||||
border-radius: 100%;
|
||||
background: white;
|
||||
}
|
||||
/* Note: :focus selectors are buggy in Edge, so we skip that */
|
560
docs/r/ctxedit.js
Normal file
@ -0,0 +1,560 @@
|
||||
var CtxEdit = (function(){
|
||||
|
||||
|
||||
function getLocalObject(key) {
|
||||
let s = sessionStorage.getItem(key)
|
||||
if (s) {
|
||||
try {
|
||||
return JSON.parse(s)
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`failed to parse sessionStorage value "${s}" for key ${key}`,
|
||||
err.stack || String(err)
|
||||
)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
function setLocalObject(key, value) {
|
||||
let json = JSON.stringify(value)
|
||||
sessionStorage.setItem(key, json)
|
||||
}
|
||||
|
||||
|
||||
function rmLocalObject(key) {
|
||||
sessionStorage.removeItem(key)
|
||||
}
|
||||
|
||||
|
||||
class FloatProp {
|
||||
constructor(cssProp, unitSuffix) {
|
||||
this.cssProp = cssProp
|
||||
this.unitSuffix = unitSuffix
|
||||
}
|
||||
|
||||
valueInStyle(s) {
|
||||
let v = s[this.cssProp]
|
||||
return v !== undefined ? parseFloat(v) : v
|
||||
}
|
||||
|
||||
applyStyle(el, value) {
|
||||
el.style[this.cssProp] = value + this.unitSuffix
|
||||
}
|
||||
}
|
||||
|
||||
class FontStyleProp {
|
||||
|
||||
valueInStyle(s) {
|
||||
let italic = s['font-style'] == 'italic' || s['font-style'].indexOf('oblique') != -1
|
||||
let weight = parseFloat(s['font-weight'])
|
||||
if (isNaN(weight)) {
|
||||
weight = s['font-weight']
|
||||
if (weight == 'thin') { return italic ? 'thin-italic' : 'thin' }
|
||||
if (weight == 'extra-light') {return italic ? 'extra-light-italic' :'extra-light' }
|
||||
if (weight == 'light') { return italic ? 'light-italic' : 'light' }
|
||||
if (weight == 'normal') { return italic ? 'italic' : 'regular' }
|
||||
if (weight == 'medium') { return italic ? 'medium-italic' : 'medium' }
|
||||
if (weight == 'semi-bold') { return italic ? 'semi-bold-italic' : 'semi-bold' }
|
||||
if (weight == 'bold') { return italic ? 'bold-italic' : 'bold' }
|
||||
if (weight == 'extra-bold') { return italic ? 'extra-bold-italic' : 'extra-bold' }
|
||||
} else {
|
||||
if (weight <= 150) { return italic ? 'thin-italic' : 'thin' }
|
||||
if (weight <= 250) { return italic ? 'extra-light-italic' :'extra-light' }
|
||||
if (weight <= 350) { return italic ? 'light-italic' : 'light' }
|
||||
if (weight <= 450) { return italic ? 'italic' : 'regular' }
|
||||
if (weight <= 550) { return italic ? 'medium-italic' : 'medium' }
|
||||
if (weight <= 650) { return italic ? 'semi-bold-italic' : 'semi-bold' }
|
||||
if (weight <= 750) { return italic ? 'bold-italic' : 'bold' }
|
||||
if (weight <= 850) { return italic ? 'extra-bold-italic' : 'extra-bold' }
|
||||
}
|
||||
return italic ? 'black-italic' : 'black'
|
||||
}
|
||||
|
||||
applyStyle(el, value) {
|
||||
let cl = el.classList
|
||||
for (let k of Array.from(cl.values())) {
|
||||
if (k.indexOf('font-style-') == 0) {
|
||||
cl.remove(k)
|
||||
}
|
||||
}
|
||||
cl.add('font-style-' + value)
|
||||
}
|
||||
}
|
||||
|
||||
class LineHeightProp {
|
||||
valueInStyle(s) {
|
||||
let v = s['line-height']
|
||||
if (v === undefined) {
|
||||
return 1.0
|
||||
}
|
||||
if (v.lastIndexOf('px') == v.length - 2) {
|
||||
// compute
|
||||
return parseFloat(
|
||||
(parseFloat(v) / parseFloat(s['font-size'])).toFixed(3)
|
||||
)
|
||||
}
|
||||
v = parseFloat(v)
|
||||
return isNaN(v) ? 1.0 : v
|
||||
}
|
||||
|
||||
applyStyle(el, value) {
|
||||
el.style['line-height'] = String(value)
|
||||
}
|
||||
}
|
||||
|
||||
class TrackingProp {
|
||||
valueInStyle(s) {
|
||||
let v = s['letter-spacing']
|
||||
if (v === undefined) {
|
||||
return 0
|
||||
}
|
||||
if (v.lastIndexOf('px') == v.length - 2) {
|
||||
// compute
|
||||
return parseFloat(
|
||||
(parseFloat(v) / parseFloat(s['font-size'])).toFixed(3)
|
||||
)
|
||||
}
|
||||
v = parseFloat(v)
|
||||
return isNaN(v) ? 0 : v
|
||||
}
|
||||
|
||||
applyStyle(el, value) {
|
||||
el.style['letter-spacing'] = value.toFixed(3) + 'em'
|
||||
}
|
||||
}
|
||||
|
||||
const Props = {
|
||||
size: new FloatProp('font-size', 'px'),
|
||||
tracking: new TrackingProp(),
|
||||
lineHeight: new LineHeightProp(),
|
||||
style: new FontStyleProp(),
|
||||
}
|
||||
|
||||
function valuesFromStyle(s) {
|
||||
let values = {}
|
||||
for (let name in Props) {
|
||||
let p = Props[name]
|
||||
values[name] = p.valueInStyle(s)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
|
||||
class Editable {
|
||||
constructor(el, key) {
|
||||
this.el = el
|
||||
this.key = key
|
||||
this.defaultValues = valuesFromStyle(getComputedStyle(this.el))
|
||||
this.values = Object.assign({}, this.defaultValues)
|
||||
this.defaultExplicitTracking = this.defaultValues['tracking'] != 0
|
||||
this.explicitTracking = this.defaultExplicitTracking
|
||||
this.explicitTrackingKey = this.key + ":etracking"
|
||||
this.loadValues()
|
||||
this.updateSizeDependantProps()
|
||||
}
|
||||
|
||||
resetValues() {
|
||||
this.values = Object.assign({}, this.defaultValues)
|
||||
let style = this.el.style
|
||||
for (let name in this.values) {
|
||||
Props[name].applyStyle(this.el, this.values[name])
|
||||
}
|
||||
rmLocalObject(this.key)
|
||||
rmLocalObject(this.explicitTrackingKey)
|
||||
this.explicitTracking = this.defaultExplicitTracking
|
||||
this.updateSizeDependantProps()
|
||||
}
|
||||
|
||||
setExplicitTracking(explicitTracking) {
|
||||
if (this.explicitTracking !== explicitTracking) {
|
||||
this.explicitTracking = explicitTracking
|
||||
if (!this.explicitTracking) {
|
||||
this.updateSizeDependantProps()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setValue(name, value) {
|
||||
this.values[name] = value
|
||||
Props[name].applyStyle(this.el, value)
|
||||
if (name == 'size') {
|
||||
this.updateSizeDependantProps()
|
||||
}
|
||||
}
|
||||
|
||||
updateSizeDependantProps() {
|
||||
let size = this.values.size
|
||||
|
||||
// dynamic tracking
|
||||
if (!this.explicitTracking) {
|
||||
this.setValue('tracking', InterDynamicTracking(size))
|
||||
}
|
||||
|
||||
// left indent
|
||||
// TODO: Consider making this part of dynamic metrics.
|
||||
let leftMargin = size / -16
|
||||
if (leftMargin == 0) {
|
||||
this.el.style.marginLeft = null
|
||||
} else {
|
||||
this.el.style.marginLeft = leftMargin.toFixed(1) + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
loadValues() {
|
||||
let values = getLocalObject(this.key)
|
||||
if (values && typeof values == 'object') {
|
||||
for (let name in values) {
|
||||
if (name in this.values) {
|
||||
let value = values[name]
|
||||
this.values[name] = value
|
||||
Props[name].applyStyle(this.el, value)
|
||||
} else if (console.warn) {
|
||||
console.warn(`Editable.loadValues ignoring unknown "${name}"`)
|
||||
}
|
||||
}
|
||||
// console.log(`loaded values for ${this}:`, values)
|
||||
}
|
||||
let etr = getLocalObject(this.explicitTrackingKey)
|
||||
this.explicitTracking = this.defaultExplicitTracking || etr
|
||||
}
|
||||
|
||||
isDefaultValues() {
|
||||
for (let k in this.values) {
|
||||
if (this.values[k] !== this.defaultValues[k]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
saveValues() {
|
||||
if (this.isDefaultValues()) {
|
||||
rmLocalObject(this.key)
|
||||
rmLocalObject(this.explicitTrackingKey)
|
||||
} else {
|
||||
setLocalObject(this.key, this.values)
|
||||
setLocalObject(this.explicitTrackingKey, this.explicitTracking ? "1" : "0")
|
||||
}
|
||||
// console.log(`saved values for ${this}`)
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `Editable(${this.key})`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var supportsFocusTrick = (u =>
|
||||
u.indexOf('Firefox/') == -1
|
||||
)(navigator.userAgent)
|
||||
|
||||
|
||||
class CtxEdit {
|
||||
constructor() {
|
||||
this.bindings = new Bindings()
|
||||
this.keyPrefix = 'ctxedit:' + document.location.pathname + ':'
|
||||
this.editables = new Map()
|
||||
this.ui = $('#ctxedit-ui')
|
||||
this.currEditable = null
|
||||
this._saveValuesTimer = null
|
||||
this.isChangingBindings = true
|
||||
this.bindings = new Bindings()
|
||||
this.initBindings()
|
||||
this.initUI()
|
||||
this.addAllEditables()
|
||||
this.isChangingBindings = false
|
||||
this.preloadFonts()
|
||||
|
||||
if (supportsFocusTrick) {
|
||||
this.ui.addEventListener('focus', ev => {
|
||||
if (this.currEditable) {
|
||||
ev.preventDefault()
|
||||
ev.stopImmediatePropagation()
|
||||
this.currEditable.el.focus() // breaks Firefox
|
||||
}
|
||||
}, {capture:true, passive:false})
|
||||
}
|
||||
}
|
||||
|
||||
initUI() {
|
||||
$('.reset-button', this.ui).addEventListener('click', ev => this.reset())
|
||||
$('.dismiss-button', this.ui).addEventListener('click', ev => this.stopEditing())
|
||||
this.initRangeSliders()
|
||||
}
|
||||
|
||||
initRangeSliders() {
|
||||
this._sliderTimers = new Map()
|
||||
$$('input[type="range"]', this.ui).forEach(input => {
|
||||
var binding = this.bindings.getBinding(input.dataset.binding)
|
||||
|
||||
// create and hook up value tip
|
||||
let valtip = document.createElement('div')
|
||||
let valtipval = document.createElement('div')
|
||||
let valtipcallout = document.createElement('div')
|
||||
valtip.className = 'slider-value-tip'
|
||||
valtipval.className = 'value'
|
||||
valtipcallout.className = 'callout'
|
||||
valtipval.innerText = '0'
|
||||
valtip.appendChild(valtipval)
|
||||
valtip.appendChild(valtipcallout)
|
||||
binding.addOutput(valtipval)
|
||||
document.body.appendChild(valtip)
|
||||
|
||||
let inputBounds = {}
|
||||
let min = parseFloat(input.getAttribute('min'))
|
||||
let max = parseFloat(input.getAttribute('max'))
|
||||
if (isNaN(min)) {
|
||||
min = 0
|
||||
}
|
||||
if (isNaN(max)) {
|
||||
max = 1
|
||||
}
|
||||
const sliderThumbWidth = 12
|
||||
const valtipYOffset = 14
|
||||
|
||||
let updateValTipXPos = () => {
|
||||
let r = (binding.value - min) / (max - min)
|
||||
let sliderWidth = inputBounds.width - sliderThumbWidth
|
||||
let x = ((inputBounds.x + (sliderThumbWidth / 2)) + (sliderWidth * r)) - (valtip.clientWidth / 2)
|
||||
valtip.style.left = x + 'px'
|
||||
}
|
||||
|
||||
binding.addListener(updateValTipXPos)
|
||||
|
||||
let shownCounter = 0
|
||||
let showValTip = () => {
|
||||
if (++shownCounter == 1) {
|
||||
valtip.classList.add('visible')
|
||||
inputBounds = input.getBoundingClientRect()
|
||||
valtip.style.top = (inputBounds.y - valtip.clientHeight + valtipYOffset) + 'px'
|
||||
updateValTipXPos()
|
||||
}
|
||||
}
|
||||
let hideValTip = () => {
|
||||
if (--shownCounter == 0) {
|
||||
valtip.classList.remove('visible')
|
||||
}
|
||||
}
|
||||
|
||||
input.addEventListener('pointerdown', showValTip)
|
||||
input.addEventListener('pointerup', hideValTip)
|
||||
input.addEventListener('pointercancel', hideValTip)
|
||||
|
||||
let timer = null
|
||||
input.addEventListener('input', ev => {
|
||||
if (timer === null) {
|
||||
showValTip()
|
||||
} else {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
hideValTip()
|
||||
}, 400)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
initBindings() {
|
||||
let b = this.bindings
|
||||
|
||||
// let updateTracking = fontSize => {
|
||||
// if (!this.currEditable.explicitTracking) {
|
||||
// var tracking = InterDynamicTracking(fontSize)
|
||||
// this.isChangingBindings = true
|
||||
// b.setValue('tracking', tracking)
|
||||
// this.isChangingBindings = false
|
||||
// }
|
||||
// }
|
||||
|
||||
b.configure('tracking', 0, 'float', tracking => {
|
||||
if (!this.isChangingBindings && !this.currEditable.explicitTracking) {
|
||||
// console.log('enabled explicit tracking')
|
||||
this.currEditable.setExplicitTracking(true)
|
||||
this.setNeedsSaveValues()
|
||||
}
|
||||
})
|
||||
b.setFormatter('tracking', v => v.toFixed(3))
|
||||
|
||||
b.configure('size', 0, 'float', size => {
|
||||
let ed = this.currEditable
|
||||
if (ed) {
|
||||
setTimeout(() => {
|
||||
// HERE BE DRAGONS! Feedback loop from Editable
|
||||
if (!ed.explicitTracking) {
|
||||
this.isChangingBindings = true
|
||||
b.setValue('tracking', ed.values.tracking)
|
||||
this.isChangingBindings = false
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
})
|
||||
|
||||
b.configure('lineHeight', 1, 'float')
|
||||
|
||||
b.bindAllInputs($$('.control input', this.ui))
|
||||
b.bindAllInputs($$('.control select', this.ui))
|
||||
|
||||
$('.control input[data-binding="tracking"]').addEventListener("dblclick", ev => {
|
||||
let ed = this.currEditable
|
||||
setTimeout(() => {
|
||||
ed.setExplicitTracking(false)
|
||||
this.setNeedsSaveValues()
|
||||
this.isChangingBindings = true
|
||||
b.setValue('tracking', ed.values.tracking)
|
||||
this.isChangingBindings = false
|
||||
}, 50)
|
||||
})
|
||||
|
||||
for (let binding of b.allBindings()) {
|
||||
binding.addListener(() => this.bindingChanged(binding))
|
||||
}
|
||||
}
|
||||
|
||||
preloadFonts() {
|
||||
// Note: This has no effect on systems supporting variable fonts.
|
||||
[
|
||||
"regular",
|
||||
"italic",
|
||||
"medium",
|
||||
"medium-italic",
|
||||
"semi-bold",
|
||||
"semi-bold-italic",
|
||||
"bold",
|
||||
"bold-italic",
|
||||
"extra-bold",
|
||||
"extra-bold-italic",
|
||||
"black",
|
||||
"black-italic",
|
||||
].forEach(style => {
|
||||
let e = document.createElement('div')
|
||||
e.className = 'font-preload font-style-' + style
|
||||
e.innerText = 'a'
|
||||
document.body.appendChild(e)
|
||||
})
|
||||
}
|
||||
|
||||
bindingChanged(binding) {
|
||||
if (this.isChangingBindings) {
|
||||
// Note: this.isChangingBindings is true when binding values are
|
||||
// changed internally, in which case we do nothing here.
|
||||
return
|
||||
}
|
||||
if (this.currEditable) {
|
||||
this.currEditable.setValue(binding.name, binding.value)
|
||||
}
|
||||
this.setNeedsSaveValues()
|
||||
}
|
||||
|
||||
reset() {
|
||||
for (let ed of this.editables.values()) {
|
||||
ed.resetValues()
|
||||
}
|
||||
this.updateBindingValues()
|
||||
}
|
||||
|
||||
updateBindingValues() {
|
||||
if (this.currEditable) {
|
||||
this.isChangingBindings = true
|
||||
this.bindings.setValues(this.currEditable.values)
|
||||
this.isChangingBindings = false
|
||||
}
|
||||
}
|
||||
|
||||
saveValues() {
|
||||
if (this._saveValuesTimer !== null) {
|
||||
clearTimeout(this._saveValuesTimer)
|
||||
this._saveValuesTimer = null
|
||||
}
|
||||
if (this.currEditable) {
|
||||
this.currEditable.saveValues()
|
||||
}
|
||||
}
|
||||
|
||||
setNeedsSaveValues() {
|
||||
if (this._saveValuesTimer !== null) {
|
||||
clearTimeout(this._saveValuesTimer)
|
||||
}
|
||||
this._saveValuesTimer = setTimeout(() => this.saveValues(), 300)
|
||||
}
|
||||
|
||||
setCurrEditable(ed) {
|
||||
if (this._saveValuesTimer !== null &&
|
||||
this.currEditable &&
|
||||
!this.isChangingBindings)
|
||||
{
|
||||
this.saveValues()
|
||||
}
|
||||
this.currEditable = ed
|
||||
this.updateBindingValues()
|
||||
if (this.currEditable) {
|
||||
this.showUI()
|
||||
} else {
|
||||
this.hideUI()
|
||||
}
|
||||
}
|
||||
|
||||
onEditableReceivedFocus(ed) {
|
||||
// console.log(`onEditableReceivedFocus ${ed}`)
|
||||
clearTimeout(this._deselectTimer)
|
||||
this.setCurrEditable(ed)
|
||||
}
|
||||
|
||||
onEditableLostFocus(ed) {
|
||||
// console.log(`onEditableLostFocus ${ed}`)
|
||||
// this.setCurrEditable(null)
|
||||
if (supportsFocusTrick) {
|
||||
this._deselectTimer = setTimeout(() => this.setCurrEditable(null), 10)
|
||||
}
|
||||
}
|
||||
|
||||
showUI() {
|
||||
this.ui.classList.add('visible')
|
||||
}
|
||||
|
||||
hideUI() {
|
||||
this.ui.classList.remove('visible')
|
||||
}
|
||||
|
||||
stopEditing() {
|
||||
if (this.currEditable) {
|
||||
this.currEditable.el.blur()
|
||||
this.setCurrEditable(null)
|
||||
}
|
||||
}
|
||||
|
||||
addAllEditables() {
|
||||
for (let el of $$('[data-ctxedit]')) {
|
||||
this.addEditable(el)
|
||||
}
|
||||
}
|
||||
|
||||
addEditable(el) {
|
||||
let key = this.keyPrefix + el.dataset.ctxedit
|
||||
let existing = this.editables.get(key)
|
||||
if (existing) {
|
||||
throw new Error(`duplicate editable ${key}`)
|
||||
}
|
||||
let ed = new Editable(el, key)
|
||||
this.editables.set(key, ed)
|
||||
this.initEditable(ed)
|
||||
// this.showUI() // XXX
|
||||
}
|
||||
|
||||
initEditable(ed) {
|
||||
// filter paste
|
||||
ed.el.addEventListener('paste', ev => {
|
||||
ev.preventDefault()
|
||||
let text = ev.clipboardData.getData("text/plain")
|
||||
document.execCommand("insertHTML", false, text)
|
||||
}, {capture:true,passive:false})
|
||||
|
||||
ed.el.addEventListener('focus', ev => this.onEditableReceivedFocus(ed))
|
||||
ed.el.addEventListener('blur', ev => this.onEditableLostFocus(ed))
|
||||
}
|
||||
}
|
||||
|
||||
return CtxEdit
|
||||
})();
|
1
docs/r/dismiss.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 9l-.354.354.354.353.354-.353L8 9zm.354.354l5-5-.708-.708-5 5 .708.708zm0-.708l-5-5-.708.708 5 5 .708-.708z" fill="#fff"/><path stroke="#fff" d="M2 12.5h12"/></svg>
|
After Width: | Height: | Size: 250 B |
239
docs/r/graphplot.js
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
function GraphPlot(canvas) {
|
||||
this.canvas = canvas
|
||||
const g = canvas.getContext('2d')
|
||||
if (g == null) {
|
||||
throw new Error('failed to acquire 2d context')
|
||||
}
|
||||
|
||||
this.width = 0 // dp
|
||||
this.height = 0 // dp
|
||||
this.widthPx = 0 // px
|
||||
this.heightPx = 0 // px
|
||||
this.pixelRatio = 1
|
||||
this.g = g
|
||||
this.dataSegments = []
|
||||
this.axes = {
|
||||
x0: .5, // % from left to x=0
|
||||
y0: .5, // % from top to y=0
|
||||
scalex: 40, // pixels from x=0 to x=1
|
||||
scaley: 40, // pixels from y=0 to y=1
|
||||
negativeX: true,
|
||||
}
|
||||
|
||||
if (!this.autosize()) {
|
||||
this.setSize(256, 256)
|
||||
}
|
||||
}
|
||||
|
||||
GraphPlot.prototype.autosize = function() {
|
||||
try {
|
||||
this.canvas.width = null
|
||||
this.canvas.height = null
|
||||
this.canvas.style.width = null
|
||||
this.canvas.style.height = null
|
||||
var cs = window.getComputedStyle(this.canvas)
|
||||
var width = parseFloat(cs.width)
|
||||
var height = parseFloat(cs.height)
|
||||
this.setSize(width, height)
|
||||
return true
|
||||
} catch (err) {
|
||||
if (typeof console != 'undefined' && console.warn) {
|
||||
console.warn('GraphPlot.autosize failed: ' + err)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// setOrigin sets the origin of axis x and y
|
||||
// The values should be in the range [0-1] and maps to the extremes
|
||||
// of the canvas.
|
||||
//
|
||||
GraphPlot.prototype.setOrigin = function(x, y) {
|
||||
var p = this
|
||||
p.axes.x0 = x
|
||||
p.axes.y0 = y
|
||||
}
|
||||
|
||||
// setScale sets the value scale for x and y axis.
|
||||
// The values should be provided as display points.
|
||||
//
|
||||
GraphPlot.prototype.setScale = function(x, y) {
|
||||
var p = this
|
||||
if (y === undefined) {
|
||||
y = x
|
||||
}
|
||||
p.axes.scalex = x
|
||||
p.axes.scaley = y
|
||||
}
|
||||
|
||||
// setSize sets the size of canvas in display points
|
||||
//
|
||||
GraphPlot.prototype.setSize = function(width, height) {
|
||||
var p = this
|
||||
p.width = width
|
||||
p.height = height
|
||||
const el = p.canvas, g = p.g
|
||||
p.pixelRatio = window.devicePixelRatio || 1
|
||||
if (p.pixelRatio != 1) {
|
||||
el.width = p.widthPx = width * p.pixelRatio
|
||||
el.height = p.heightPx = height * p.pixelRatio
|
||||
g.scale(p.pixelRatio, p.pixelRatio)
|
||||
} else {
|
||||
el.width = p.widthPx = width
|
||||
el.height = p.heightPx = height
|
||||
g.scale(1, 1)
|
||||
}
|
||||
el.style.width = `${width}px`
|
||||
el.style.height = `${height}px`
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.renderAxes = function() {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = Math.round(p.axes.x0 * p.widthPx) / p.pixelRatio
|
||||
, y0 = Math.round(p.axes.y0 * p.heightPx) / p.pixelRatio
|
||||
|
||||
g.beginPath()
|
||||
g.strokeStyle = "rgb(0, 0, 0, 0.2)"
|
||||
if (y0 > 0 && y0 < p.width) {
|
||||
g.moveTo(0, y0); g.lineTo(p.width, y0) // X axis
|
||||
}
|
||||
if (x0 > 0 && x0 < p.height) {
|
||||
g.moveTo(x0, 0); g.lineTo(x0, p.height) // Y axis
|
||||
}
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotf plots an arbitrary function on the graph
|
||||
//
|
||||
GraphPlot.prototype.plotf = function(f, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, w = p.width
|
||||
, h = p.height
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, dx = 4 / p.pixelRatio // smaller means finer curves and more CPU
|
||||
, scalex = p.axes.scalex * w
|
||||
, scaley = p.axes.scaley * h
|
||||
, iMax = Math.round((w - x0) / dx)
|
||||
, iMin = p.axes.negativeX ? Math.round(-x0 / dx) : 0
|
||||
|
||||
g.beginPath()
|
||||
g.lineWidth = 1
|
||||
g.strokeStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
for (var i = iMin; i <= iMax; i++) {
|
||||
x = dx * i
|
||||
y = f(x / scalex) * scaley
|
||||
if (i == iMin) {
|
||||
g.moveTo(x0 + x, y0 - y)
|
||||
} else {
|
||||
g.lineTo(x0 + x, y0 - y)
|
||||
}
|
||||
}
|
||||
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotLines draws straight lines between a collection of points
|
||||
//
|
||||
GraphPlot.prototype.plotLine = function(points, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, scalex = p.axes.scalex * p.width
|
||||
, scaley = p.axes.scaley * p.height
|
||||
, pt
|
||||
|
||||
g.beginPath()
|
||||
g.lineWidth = 1
|
||||
g.strokeStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
var i = 0
|
||||
for (; i < points.length; i++) {
|
||||
pt = points[i]
|
||||
x = pt[0] * scalex
|
||||
y = pt[1] * scaley
|
||||
if (i == 0) {
|
||||
g.moveTo(x0 + x, y0 - y)
|
||||
} else {
|
||||
g.lineTo(x0 + x, y0 - y)
|
||||
}
|
||||
}
|
||||
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
|
||||
// plotPoints draws points
|
||||
//
|
||||
GraphPlot.prototype.plotPoints = function(points, color) {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, x0 = p.axes.x0 * p.width
|
||||
, y0 = p.axes.y0 * p.height
|
||||
, x = 0
|
||||
, y = 0
|
||||
, scalex = p.axes.scalex * p.width
|
||||
, scaley = p.axes.scaley * p.height
|
||||
, pt
|
||||
, i = 0
|
||||
|
||||
g.fillStyle = color || "rgb(0, 0, 0, 0.8)"
|
||||
|
||||
for (; i < points.length; i++) {
|
||||
pt = points[i]
|
||||
x = x0 + pt[0] * scalex
|
||||
y = y0 - pt[1] * scaley
|
||||
g.beginPath()
|
||||
g.arc(x, y, 3, 0, Math.PI + (Math.PI * 2) / 2, false)
|
||||
g.fill()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.clear = function() {
|
||||
var p = this
|
||||
p.g.clearRect(0, 0, p.width, p.height)
|
||||
p.renderAxes()
|
||||
}
|
||||
|
||||
|
||||
GraphPlot.prototype.renderDemo = function() {
|
||||
var p = this
|
||||
, g = p.g
|
||||
, dpscale = p.pixelRatio
|
||||
, w = p.widthPx
|
||||
, h = p.heightPx
|
||||
|
||||
p.clear()
|
||||
|
||||
p.plotf(
|
||||
function(x) { return Math.sin(x) },
|
||||
'blue'
|
||||
)
|
||||
|
||||
p.plotf(
|
||||
function(x) { return Math.cos(3*x) },
|
||||
'hotpink'
|
||||
)
|
||||
|
||||
// var scale = p.height / 4
|
||||
// g.moveTo(0, scale)
|
||||
// var i, sine, lines = 200, frag = p.width / lines
|
||||
// for (i = 0; i < lines; i++) {
|
||||
// sine = Math.sin(i / scale * 2) * scale
|
||||
// g.lineTo(i * frag, -sine + scale)
|
||||
// }
|
||||
// g.stroke()
|
||||
}
|
341
docs/r/grid.css
Normal file
@ -0,0 +1,341 @@
|
||||
/* Raster Simple CSS Grid System, version 3 */
|
||||
grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
--grid-cs: 1; /* start */
|
||||
--grid-ce: -1 /* end */
|
||||
}
|
||||
|
||||
/* c -- cell or column */
|
||||
grid > c { display: block; appearance: none; -webkit-appearance: none }
|
||||
|
||||
grid[columns="1"] { grid-template-columns: repeat(1, 1fr) }
|
||||
grid[columns="2"] { grid-template-columns: repeat(2, 1fr) }
|
||||
grid[columns="3"] { grid-template-columns: repeat(3, 1fr) }
|
||||
grid[columns="4"] { grid-template-columns: repeat(4, 1fr) }
|
||||
grid[columns="5"] { grid-template-columns: repeat(5, 1fr) }
|
||||
grid[columns="6"] { grid-template-columns: repeat(6, 1fr) }
|
||||
grid[columns="7"] { grid-template-columns: repeat(7, 1fr) }
|
||||
grid[columns="8"] { grid-template-columns: repeat(8, 1fr) }
|
||||
grid[columns="9"] { grid-template-columns: repeat(9, 1fr) }
|
||||
grid[columns="10"] { grid-template-columns: repeat(10, 1fr) }
|
||||
grid[columns="11"] { grid-template-columns: repeat(11, 1fr) }
|
||||
grid[columns="12"] { grid-template-columns: repeat(12, 1fr) }
|
||||
grid[columns="13"] { grid-template-columns: repeat(13, 1fr) }
|
||||
grid[columns="14"] { grid-template-columns: repeat(14, 1fr) }
|
||||
grid[columns="15"] { grid-template-columns: repeat(15, 1fr) }
|
||||
grid[columns="16"] { grid-template-columns: repeat(16, 1fr) }
|
||||
grid[columns="17"] { grid-template-columns: repeat(17, 1fr) }
|
||||
grid[columns="18"] { grid-template-columns: repeat(18, 1fr) }
|
||||
grid[columns="19"] { grid-template-columns: repeat(19, 1fr) }
|
||||
grid[columns="20"] { grid-template-columns: repeat(20, 1fr) }
|
||||
grid[columns="21"] { grid-template-columns: repeat(21, 1fr) }
|
||||
grid[columns="22"] { grid-template-columns: repeat(22, 1fr) }
|
||||
grid[columns="23"] { grid-template-columns: repeat(23, 1fr) }
|
||||
grid[columns="24"] { grid-template-columns: repeat(24, 1fr) }
|
||||
grid[columns="25"] { grid-template-columns: repeat(25, 1fr) }
|
||||
grid[columns="26"] { grid-template-columns: repeat(26, 1fr) }
|
||||
grid[columns="27"] { grid-template-columns: repeat(27, 1fr) }
|
||||
grid[columns="28"] { grid-template-columns: repeat(28, 1fr) }
|
||||
grid[columns="29"] { grid-template-columns: repeat(29, 1fr) }
|
||||
grid[columns="30"] { grid-template-columns: repeat(30, 1fr) }
|
||||
|
||||
/* span=start... */
|
||||
grid > c[span^="1"] { --grid-cs: 1 }
|
||||
grid > c[span^="2"] { --grid-cs: 2 }
|
||||
grid > c[span^="3"] { --grid-cs: 3 }
|
||||
grid > c[span^="4"] { --grid-cs: 4 }
|
||||
grid > c[span^="5"] { --grid-cs: 5 }
|
||||
grid > c[span^="6"] { --grid-cs: 6 }
|
||||
grid > c[span^="7"] { --grid-cs: 7 }
|
||||
grid > c[span^="8"] { --grid-cs: 8 }
|
||||
grid > c[span^="9"] { --grid-cs: 9 }
|
||||
grid > c[span^="10"] { --grid-cs: 10 }
|
||||
grid > c[span^="11"] { --grid-cs: 11 }
|
||||
grid > c[span^="12"] { --grid-cs: 12 }
|
||||
grid > c[span^="13"] { --grid-cs: 13 }
|
||||
grid > c[span^="14"] { --grid-cs: 14 }
|
||||
grid > c[span^="15"] { --grid-cs: 15 }
|
||||
grid > c[span^="16"] { --grid-cs: 16 }
|
||||
grid > c[span^="17"] { --grid-cs: 17 }
|
||||
grid > c[span^="18"] { --grid-cs: 18 }
|
||||
grid > c[span^="19"] { --grid-cs: 19 }
|
||||
grid > c[span^="20"] { --grid-cs: 20 }
|
||||
grid > c[span^="21"] { --grid-cs: 21 }
|
||||
grid > c[span^="22"] { --grid-cs: 22 }
|
||||
grid > c[span^="23"] { --grid-cs: 23 }
|
||||
grid > c[span^="24"] { --grid-cs: 24 }
|
||||
grid > c[span^="25"] { --grid-cs: 25 }
|
||||
grid > c[span^="26"] { --grid-cs: 26 }
|
||||
grid > c[span^="27"] { --grid-cs: 27 }
|
||||
grid > c[span^="28"] { --grid-cs: 28 }
|
||||
grid > c[span^="29"] { --grid-cs: 29 }
|
||||
grid > c[span^="30"] { --grid-cs: 30 }
|
||||
|
||||
/* span=...+width, span=...-end */
|
||||
grid > c[span$="+1"], grid > c[span="1"] { --grid-ce: 1 }
|
||||
grid > c[span$="+2"], grid > c[span$="-1"], grid > c[span="2"] { --grid-ce: 2 }
|
||||
grid > c[span$="+3"], grid > c[span$="-2"], grid > c[span="3"] { --grid-ce: 3 }
|
||||
grid > c[span$="+4"], grid > c[span$="-3"], grid > c[span="4"] { --grid-ce: 4 }
|
||||
grid > c[span$="+5"], grid > c[span$="-4"], grid > c[span="5"] { --grid-ce: 5 }
|
||||
grid > c[span$="+6"], grid > c[span$="-5"], grid > c[span="6"] { --grid-ce: 6 }
|
||||
grid > c[span$="+7"], grid > c[span$="-6"], grid > c[span="7"] { --grid-ce: 7 }
|
||||
grid > c[span$="+8"], grid > c[span$="-7"], grid > c[span="8"] { --grid-ce: 8 }
|
||||
grid > c[span$="+9"], grid > c[span$="-8"], grid > c[span="9"] { --grid-ce: 9 }
|
||||
grid > c[span$="+10"], grid > c[span$="-9"], grid > c[span="10"] { --grid-ce: 10 }
|
||||
grid > c[span$="+11"], grid > c[span$="-10"], grid > c[span="11"] { --grid-ce: 11 }
|
||||
grid > c[span$="+12"], grid > c[span$="-11"], grid > c[span="12"] { --grid-ce: 12 }
|
||||
grid > c[span$="+13"], grid > c[span$="-12"], grid > c[span="13"] { --grid-ce: 13 }
|
||||
grid > c[span$="+14"], grid > c[span$="-13"], grid > c[span="14"] { --grid-ce: 14 }
|
||||
grid > c[span$="+15"], grid > c[span$="-14"], grid > c[span="15"] { --grid-ce: 15 }
|
||||
grid > c[span$="+16"], grid > c[span$="-15"], grid > c[span="16"] { --grid-ce: 16 }
|
||||
grid > c[span$="+17"], grid > c[span$="-16"], grid > c[span="17"] { --grid-ce: 17 }
|
||||
grid > c[span$="+18"], grid > c[span$="-17"], grid > c[span="18"] { --grid-ce: 18 }
|
||||
grid > c[span$="+19"], grid > c[span$="-18"], grid > c[span="19"] { --grid-ce: 19 }
|
||||
grid > c[span$="+20"], grid > c[span$="-19"], grid > c[span="20"] { --grid-ce: 20 }
|
||||
grid > c[span$="+21"], grid > c[span$="-20"], grid > c[span="21"] { --grid-ce: 21 }
|
||||
grid > c[span$="+22"], grid > c[span$="-21"], grid > c[span="22"] { --grid-ce: 22 }
|
||||
grid > c[span$="+23"], grid > c[span$="-22"], grid > c[span="23"] { --grid-ce: 23 }
|
||||
grid > c[span$="+24"], grid > c[span$="-23"], grid > c[span="24"] { --grid-ce: 24 }
|
||||
grid > c[span$="+25"], grid > c[span$="-24"], grid > c[span="25"] { --grid-ce: 25 }
|
||||
grid > c[span$="+26"], grid > c[span$="-25"], grid > c[span="26"] { --grid-ce: 26 }
|
||||
grid > c[span$="+27"], grid > c[span$="-26"], grid > c[span="27"] { --grid-ce: 27 }
|
||||
grid > c[span$="+28"], grid > c[span$="-27"], grid > c[span="28"] { --grid-ce: 28 }
|
||||
grid > c[span$="+29"], grid > c[span$="-28"], grid > c[span="29"] { --grid-ce: 29 }
|
||||
grid > c[span$="+30"], grid > c[span$="-29"], grid > c[span="30"] { --grid-ce: 30 }
|
||||
grid > c[span$="-30"] { --grid-ce: 31 }
|
||||
|
||||
/* connect vars */
|
||||
grid > c[span] { grid-column-end: span var(--grid-ce) }
|
||||
grid > c[span*="+"], grid > c[span*="-"], grid > c[span*=".."] {
|
||||
grid-column-start: var(--grid-cs) }
|
||||
grid > c[span*="-"], grid > c[span*=".."] {
|
||||
grid-column-end: var(--grid-ce) }
|
||||
grid > c[span="row"] { grid-column: 1 / -1 }
|
||||
|
||||
/* for window width <= 600 */
|
||||
@media only screen and (max-width: 600px) {
|
||||
grid[columns-s="1"] { grid-template-columns: repeat(1, 1fr) }
|
||||
grid[columns-s="2"] { grid-template-columns: repeat(2, 1fr) }
|
||||
grid[columns-s="3"] { grid-template-columns: repeat(3, 1fr) }
|
||||
grid[columns-s="4"] { grid-template-columns: repeat(4, 1fr) }
|
||||
grid[columns-s="5"] { grid-template-columns: repeat(5, 1fr) }
|
||||
grid[columns-s="6"] { grid-template-columns: repeat(6, 1fr) }
|
||||
grid[columns-s="7"] { grid-template-columns: repeat(7, 1fr) }
|
||||
grid[columns-s="8"] { grid-template-columns: repeat(8, 1fr) }
|
||||
grid[columns-s="9"] { grid-template-columns: repeat(9, 1fr) }
|
||||
grid[columns-s="10"] { grid-template-columns: repeat(10, 1fr) }
|
||||
grid[columns-s="11"] { grid-template-columns: repeat(11, 1fr) }
|
||||
grid[columns-s="12"] { grid-template-columns: repeat(12, 1fr) }
|
||||
grid[columns-s="13"] { grid-template-columns: repeat(13, 1fr) }
|
||||
grid[columns-s="14"] { grid-template-columns: repeat(14, 1fr) }
|
||||
grid[columns-s="15"] { grid-template-columns: repeat(15, 1fr) }
|
||||
grid[columns-s="16"] { grid-template-columns: repeat(16, 1fr) }
|
||||
grid[columns-s="17"] { grid-template-columns: repeat(17, 1fr) }
|
||||
grid[columns-s="18"] { grid-template-columns: repeat(18, 1fr) }
|
||||
grid[columns-s="19"] { grid-template-columns: repeat(19, 1fr) }
|
||||
grid[columns-s="20"] { grid-template-columns: repeat(20, 1fr) }
|
||||
grid[columns-s="21"] { grid-template-columns: repeat(21, 1fr) }
|
||||
grid[columns-s="22"] { grid-template-columns: repeat(22, 1fr) }
|
||||
grid[columns-s="23"] { grid-template-columns: repeat(23, 1fr) }
|
||||
grid[columns-s="24"] { grid-template-columns: repeat(24, 1fr) }
|
||||
grid[columns-s="25"] { grid-template-columns: repeat(25, 1fr) }
|
||||
grid[columns-s="26"] { grid-template-columns: repeat(26, 1fr) }
|
||||
grid[columns-s="27"] { grid-template-columns: repeat(27, 1fr) }
|
||||
grid[columns-s="28"] { grid-template-columns: repeat(28, 1fr) }
|
||||
grid[columns-s="29"] { grid-template-columns: repeat(29, 1fr) }
|
||||
grid[columns-s="30"] { grid-template-columns: repeat(30, 1fr) }
|
||||
|
||||
/* span-s=start... */
|
||||
grid > c[span-s^="1"] { --grid-cs: 1 }
|
||||
grid > c[span-s^="2"] { --grid-cs: 2 }
|
||||
grid > c[span-s^="3"] { --grid-cs: 3 }
|
||||
grid > c[span-s^="4"] { --grid-cs: 4 }
|
||||
grid > c[span-s^="5"] { --grid-cs: 5 }
|
||||
grid > c[span-s^="6"] { --grid-cs: 6 }
|
||||
grid > c[span-s^="7"] { --grid-cs: 7 }
|
||||
grid > c[span-s^="8"] { --grid-cs: 8 }
|
||||
grid > c[span-s^="9"] { --grid-cs: 9 }
|
||||
grid > c[span-s^="10"] { --grid-cs: 10 }
|
||||
grid > c[span-s^="11"] { --grid-cs: 11 }
|
||||
grid > c[span-s^="12"] { --grid-cs: 12 }
|
||||
grid > c[span-s^="13"] { --grid-cs: 13 }
|
||||
grid > c[span-s^="14"] { --grid-cs: 14 }
|
||||
grid > c[span-s^="15"] { --grid-cs: 15 }
|
||||
grid > c[span-s^="16"] { --grid-cs: 16 }
|
||||
grid > c[span-s^="17"] { --grid-cs: 17 }
|
||||
grid > c[span-s^="18"] { --grid-cs: 18 }
|
||||
grid > c[span-s^="19"] { --grid-cs: 19 }
|
||||
grid > c[span-s^="20"] { --grid-cs: 20 }
|
||||
grid > c[span-s^="21"] { --grid-cs: 21 }
|
||||
grid > c[span-s^="22"] { --grid-cs: 22 }
|
||||
grid > c[span-s^="23"] { --grid-cs: 23 }
|
||||
grid > c[span-s^="24"] { --grid-cs: 24 }
|
||||
grid > c[span-s^="25"] { --grid-cs: 25 }
|
||||
grid > c[span-s^="26"] { --grid-cs: 26 }
|
||||
grid > c[span-s^="27"] { --grid-cs: 27 }
|
||||
grid > c[span-s^="28"] { --grid-cs: 28 }
|
||||
grid > c[span-s^="29"] { --grid-cs: 29 }
|
||||
grid > c[span-s^="30"] { --grid-cs: 30 }
|
||||
|
||||
/* span-s=...+width, span-s=...-end */
|
||||
grid > c[span-s$="+1"], grid > c[span-s="1"] { --grid-ce: 1 }
|
||||
grid > c[span-s$="+2"], grid > c[span-s$="-1"], grid > c[span-s="2"] { --grid-ce: 2 }
|
||||
grid > c[span-s$="+3"], grid > c[span-s$="-2"], grid > c[span-s="3"] { --grid-ce: 3 }
|
||||
grid > c[span-s$="+4"], grid > c[span-s$="-3"], grid > c[span-s="4"] { --grid-ce: 4 }
|
||||
grid > c[span-s$="+5"], grid > c[span-s$="-4"], grid > c[span-s="5"] { --grid-ce: 5 }
|
||||
grid > c[span-s$="+6"], grid > c[span-s$="-5"], grid > c[span-s="6"] { --grid-ce: 6 }
|
||||
grid > c[span-s$="+7"], grid > c[span-s$="-6"], grid > c[span-s="7"] { --grid-ce: 7 }
|
||||
grid > c[span-s$="+8"], grid > c[span-s$="-7"], grid > c[span-s="8"] { --grid-ce: 8 }
|
||||
grid > c[span-s$="+9"], grid > c[span-s$="-8"], grid > c[span-s="9"] { --grid-ce: 9 }
|
||||
grid > c[span-s$="+10"], grid > c[span-s$="-9"], grid > c[span-s="10"] { --grid-ce: 10 }
|
||||
grid > c[span-s$="+11"], grid > c[span-s$="-10"], grid > c[span-s="11"] { --grid-ce: 11 }
|
||||
grid > c[span-s$="+12"], grid > c[span-s$="-11"], grid > c[span-s="12"] { --grid-ce: 12 }
|
||||
grid > c[span-s$="+13"], grid > c[span-s$="-12"], grid > c[span-s="13"] { --grid-ce: 13 }
|
||||
grid > c[span-s$="+14"], grid > c[span-s$="-13"], grid > c[span-s="14"] { --grid-ce: 14 }
|
||||
grid > c[span-s$="+15"], grid > c[span-s$="-14"], grid > c[span-s="15"] { --grid-ce: 15 }
|
||||
grid > c[span-s$="+16"], grid > c[span-s$="-15"], grid > c[span-s="16"] { --grid-ce: 16 }
|
||||
grid > c[span-s$="+17"], grid > c[span-s$="-16"], grid > c[span-s="17"] { --grid-ce: 17 }
|
||||
grid > c[span-s$="+18"], grid > c[span-s$="-17"], grid > c[span-s="18"] { --grid-ce: 18 }
|
||||
grid > c[span-s$="+19"], grid > c[span-s$="-18"], grid > c[span-s="19"] { --grid-ce: 19 }
|
||||
grid > c[span-s$="+20"], grid > c[span-s$="-19"], grid > c[span-s="20"] { --grid-ce: 20 }
|
||||
grid > c[span-s$="+21"], grid > c[span-s$="-20"], grid > c[span-s="21"] { --grid-ce: 21 }
|
||||
grid > c[span-s$="+22"], grid > c[span-s$="-21"], grid > c[span-s="22"] { --grid-ce: 22 }
|
||||
grid > c[span-s$="+23"], grid > c[span-s$="-22"], grid > c[span-s="23"] { --grid-ce: 23 }
|
||||
grid > c[span-s$="+24"], grid > c[span-s$="-23"], grid > c[span-s="24"] { --grid-ce: 24 }
|
||||
grid > c[span-s$="+25"], grid > c[span-s$="-24"], grid > c[span-s="25"] { --grid-ce: 25 }
|
||||
grid > c[span-s$="+26"], grid > c[span-s$="-25"], grid > c[span-s="26"] { --grid-ce: 26 }
|
||||
grid > c[span-s$="+27"], grid > c[span-s$="-26"], grid > c[span-s="27"] { --grid-ce: 27 }
|
||||
grid > c[span-s$="+28"], grid > c[span-s$="-27"], grid > c[span-s="28"] { --grid-ce: 28 }
|
||||
grid > c[span-s$="+29"], grid > c[span-s$="-28"], grid > c[span-s="29"] { --grid-ce: 29 }
|
||||
grid > c[span-s$="+30"], grid > c[span-s$="-29"], grid > c[span-s="30"] { --grid-ce: 30 }
|
||||
grid > c[span-s$="-30"] { --grid-ce: 31 }
|
||||
|
||||
/* connect vars */
|
||||
grid > c[span-s] { grid-column-end: span var(--grid-ce) }
|
||||
grid > c[span-s*="+"], grid > c[span-s*="-"], grid > c[span-s*=".."] {
|
||||
grid-column-start: var(--grid-cs) }
|
||||
grid > c[span-s*="-"], grid > c[span-s*=".."] {
|
||||
grid-column-end: var(--grid-ce) }
|
||||
grid > c[span-s="row"] { grid-column: 1 / -1 }
|
||||
}
|
||||
|
||||
/* for window width >= 1600 */
|
||||
@media only screen and (min-width: 1599px) {
|
||||
grid[columns-l="1"] { grid-template-columns: repeat(1, 1fr) }
|
||||
grid[columns-l="2"] { grid-template-columns: repeat(2, 1fr) }
|
||||
grid[columns-l="3"] { grid-template-columns: repeat(3, 1fr) }
|
||||
grid[columns-l="4"] { grid-template-columns: repeat(4, 1fr) }
|
||||
grid[columns-l="5"] { grid-template-columns: repeat(5, 1fr) }
|
||||
grid[columns-l="6"] { grid-template-columns: repeat(6, 1fr) }
|
||||
grid[columns-l="7"] { grid-template-columns: repeat(7, 1fr) }
|
||||
grid[columns-l="8"] { grid-template-columns: repeat(8, 1fr) }
|
||||
grid[columns-l="9"] { grid-template-columns: repeat(9, 1fr) }
|
||||
grid[columns-l="10"] { grid-template-columns: repeat(10, 1fr) }
|
||||
grid[columns-l="11"] { grid-template-columns: repeat(11, 1fr) }
|
||||
grid[columns-l="12"] { grid-template-columns: repeat(12, 1fr) }
|
||||
grid[columns-l="13"] { grid-template-columns: repeat(13, 1fr) }
|
||||
grid[columns-l="14"] { grid-template-columns: repeat(14, 1fr) }
|
||||
grid[columns-l="15"] { grid-template-columns: repeat(15, 1fr) }
|
||||
grid[columns-l="16"] { grid-template-columns: repeat(16, 1fr) }
|
||||
grid[columns-l="17"] { grid-template-columns: repeat(17, 1fr) }
|
||||
grid[columns-l="18"] { grid-template-columns: repeat(18, 1fr) }
|
||||
grid[columns-l="19"] { grid-template-columns: repeat(19, 1fr) }
|
||||
grid[columns-l="20"] { grid-template-columns: repeat(20, 1fr) }
|
||||
grid[columns-l="21"] { grid-template-columns: repeat(21, 1fr) }
|
||||
grid[columns-l="22"] { grid-template-columns: repeat(22, 1fr) }
|
||||
grid[columns-l="23"] { grid-template-columns: repeat(23, 1fr) }
|
||||
grid[columns-l="24"] { grid-template-columns: repeat(24, 1fr) }
|
||||
grid[columns-l="25"] { grid-template-columns: repeat(25, 1fr) }
|
||||
grid[columns-l="26"] { grid-template-columns: repeat(26, 1fr) }
|
||||
grid[columns-l="27"] { grid-template-columns: repeat(27, 1fr) }
|
||||
grid[columns-l="28"] { grid-template-columns: repeat(28, 1fr) }
|
||||
grid[columns-l="29"] { grid-template-columns: repeat(29, 1fr) }
|
||||
grid[columns-l="30"] { grid-template-columns: repeat(30, 1fr) }
|
||||
|
||||
/* span-l=start... */
|
||||
grid > c[span-l^="1"] { --grid-cs: 1 }
|
||||
grid > c[span-l^="2"] { --grid-cs: 2 }
|
||||
grid > c[span-l^="3"] { --grid-cs: 3 }
|
||||
grid > c[span-l^="4"] { --grid-cs: 4 }
|
||||
grid > c[span-l^="5"] { --grid-cs: 5 }
|
||||
grid > c[span-l^="6"] { --grid-cs: 6 }
|
||||
grid > c[span-l^="7"] { --grid-cs: 7 }
|
||||
grid > c[span-l^="8"] { --grid-cs: 8 }
|
||||
grid > c[span-l^="9"] { --grid-cs: 9 }
|
||||
grid > c[span-l^="10"] { --grid-cs: 10 }
|
||||
grid > c[span-l^="11"] { --grid-cs: 11 }
|
||||
grid > c[span-l^="12"] { --grid-cs: 12 }
|
||||
grid > c[span-l^="13"] { --grid-cs: 13 }
|
||||
grid > c[span-l^="14"] { --grid-cs: 14 }
|
||||
grid > c[span-l^="15"] { --grid-cs: 15 }
|
||||
grid > c[span-l^="16"] { --grid-cs: 16 }
|
||||
grid > c[span-l^="17"] { --grid-cs: 17 }
|
||||
grid > c[span-l^="18"] { --grid-cs: 18 }
|
||||
grid > c[span-l^="19"] { --grid-cs: 19 }
|
||||
grid > c[span-l^="20"] { --grid-cs: 20 }
|
||||
grid > c[span-l^="21"] { --grid-cs: 21 }
|
||||
grid > c[span-l^="22"] { --grid-cs: 22 }
|
||||
grid > c[span-l^="23"] { --grid-cs: 23 }
|
||||
grid > c[span-l^="24"] { --grid-cs: 24 }
|
||||
grid > c[span-l^="25"] { --grid-cs: 25 }
|
||||
grid > c[span-l^="26"] { --grid-cs: 26 }
|
||||
grid > c[span-l^="27"] { --grid-cs: 27 }
|
||||
grid > c[span-l^="28"] { --grid-cs: 28 }
|
||||
grid > c[span-l^="29"] { --grid-cs: 29 }
|
||||
grid > c[span-l^="30"] { --grid-cs: 30 }
|
||||
|
||||
/* span-l=...+width, span-l=...-end */
|
||||
grid > c[span-l$="+1"], grid > c[span-l="1"] { --grid-ce: 1 }
|
||||
grid > c[span-l$="+2"], grid > c[span-l$="-1"], grid > c[span-l="2"] { --grid-ce: 2 }
|
||||
grid > c[span-l$="+3"], grid > c[span-l$="-2"], grid > c[span-l="3"] { --grid-ce: 3 }
|
||||
grid > c[span-l$="+4"], grid > c[span-l$="-3"], grid > c[span-l="4"] { --grid-ce: 4 }
|
||||
grid > c[span-l$="+5"], grid > c[span-l$="-4"], grid > c[span-l="5"] { --grid-ce: 5 }
|
||||
grid > c[span-l$="+6"], grid > c[span-l$="-5"], grid > c[span-l="6"] { --grid-ce: 6 }
|
||||
grid > c[span-l$="+7"], grid > c[span-l$="-6"], grid > c[span-l="7"] { --grid-ce: 7 }
|
||||
grid > c[span-l$="+8"], grid > c[span-l$="-7"], grid > c[span-l="8"] { --grid-ce: 8 }
|
||||
grid > c[span-l$="+9"], grid > c[span-l$="-8"], grid > c[span-l="9"] { --grid-ce: 9 }
|
||||
grid > c[span-l$="+10"], grid > c[span-l$="-9"], grid > c[span-l="10"] { --grid-ce: 10 }
|
||||
grid > c[span-l$="+11"], grid > c[span-l$="-10"], grid > c[span-l="11"] { --grid-ce: 11 }
|
||||
grid > c[span-l$="+12"], grid > c[span-l$="-11"], grid > c[span-l="12"] { --grid-ce: 12 }
|
||||
grid > c[span-l$="+13"], grid > c[span-l$="-12"], grid > c[span-l="13"] { --grid-ce: 13 }
|
||||
grid > c[span-l$="+14"], grid > c[span-l$="-13"], grid > c[span-l="14"] { --grid-ce: 14 }
|
||||
grid > c[span-l$="+15"], grid > c[span-l$="-14"], grid > c[span-l="15"] { --grid-ce: 15 }
|
||||
grid > c[span-l$="+16"], grid > c[span-l$="-15"], grid > c[span-l="16"] { --grid-ce: 16 }
|
||||
grid > c[span-l$="+17"], grid > c[span-l$="-16"], grid > c[span-l="17"] { --grid-ce: 17 }
|
||||
grid > c[span-l$="+18"], grid > c[span-l$="-17"], grid > c[span-l="18"] { --grid-ce: 18 }
|
||||
grid > c[span-l$="+19"], grid > c[span-l$="-18"], grid > c[span-l="19"] { --grid-ce: 19 }
|
||||
grid > c[span-l$="+20"], grid > c[span-l$="-19"], grid > c[span-l="20"] { --grid-ce: 20 }
|
||||
grid > c[span-l$="+21"], grid > c[span-l$="-20"], grid > c[span-l="21"] { --grid-ce: 21 }
|
||||
grid > c[span-l$="+22"], grid > c[span-l$="-21"], grid > c[span-l="22"] { --grid-ce: 22 }
|
||||
grid > c[span-l$="+23"], grid > c[span-l$="-22"], grid > c[span-l="23"] { --grid-ce: 23 }
|
||||
grid > c[span-l$="+24"], grid > c[span-l$="-23"], grid > c[span-l="24"] { --grid-ce: 24 }
|
||||
grid > c[span-l$="+25"], grid > c[span-l$="-24"], grid > c[span-l="25"] { --grid-ce: 25 }
|
||||
grid > c[span-l$="+26"], grid > c[span-l$="-25"], grid > c[span-l="26"] { --grid-ce: 26 }
|
||||
grid > c[span-l$="+27"], grid > c[span-l$="-26"], grid > c[span-l="27"] { --grid-ce: 27 }
|
||||
grid > c[span-l$="+28"], grid > c[span-l$="-27"], grid > c[span-l="28"] { --grid-ce: 28 }
|
||||
grid > c[span-l$="+29"], grid > c[span-l$="-28"], grid > c[span-l="29"] { --grid-ce: 29 }
|
||||
grid > c[span-l$="+30"], grid > c[span-l$="-29"], grid > c[span-l="30"] { --grid-ce: 30 }
|
||||
grid > c[span-l$="-30"] { --grid-ce: 31 }
|
||||
|
||||
/* connect vars */
|
||||
grid > c[span-l] { grid-column-end: span var(--grid-ce) }
|
||||
grid > c[span-l*="+"], grid > c[span-l*="-"], grid > c[span-l*=".."] {
|
||||
grid-column-start: var(--grid-cs) }
|
||||
grid > c[span-l*="-"], grid > c[span-l*=".."] {
|
||||
grid-column-end: var(--grid-ce) }
|
||||
grid > c[span-l="row"] { grid-column: 1 / -1 }
|
||||
}
|
||||
|
||||
/* .debug can be added to a grid to visualize its effective cells */
|
||||
grid.debug > * {
|
||||
--color: rgba(248,110,91 ,0.3);
|
||||
background-image:
|
||||
linear-gradient(to bottom, var(--color) 0%, var(--color) 100%);
|
||||
}
|
||||
grid.debug > :nth-child(6n+2) { --color: rgba(103,126,208,0.3) }
|
||||
grid.debug > :nth-child(6n+3) { --color: rgba(224,174,72 ,0.3) }
|
||||
grid.debug > :nth-child(6n+4) { --color: rgba(77, 214,115,0.3) }
|
||||
grid.debug > :nth-child(6n+5) { --color: rgba(217,103,219,0.3) }
|
||||
grid.debug > :nth-child(6n+6) { --color: rgba(94, 204,211,0.3) }
|
||||
grid.debug > :nth-child(6n+7) { --color: rgba(248,110,91 ,0.3) }
|
1
docs/r/icons/close-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 8.707l4.646 4.647.708-.708L8.707 8l4.647-4.646-.708-.708L8 7.293 3.354 2.646l-.708.708L7.293 8l-4.647 4.646.708.708L8 8.707z" fill="#000"/></svg>
|
After Width: | Height: | Size: 232 B |
1
docs/r/icons/close.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 8.707l4.646 4.647.708-.708L8.707 8l4.647-4.646-.708-.708L8 7.293 3.354 2.646l-.708.708L7.293 8l-4.647 4.646.708.708L8 8.707z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 232 B |
1
docs/r/icons/dismiss-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.293L3.354 3.646l-.708.708L8 9.707l5.354-5.353-.708-.708L8 8.293zM14 13H2v-1h12v1z" fill="#000"/></svg>
|
After Width: | Height: | Size: 231 B |
1
docs/r/icons/dismiss.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.293L3.354 3.646l-.708.708L8 9.707l5.354-5.353-.708-.708L8 8.293zM14 13H2v-1h12v1z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 231 B |
1
docs/r/icons/font-size-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.245 12l.37-1.084h1.95L4.935 12h1.052L4.11 6.91H3.068L1.191 12h1.054zM3.56 8.147h.06l.671 1.964H2.89l.671-1.964zM8.415 12l.822-2.335h3.64L13.698 12h1.108l-3.205-8.727h-1.09L7.306 12h1.108zm2.59-7.347h.103l1.436 4.074H9.57l1.436-4.074z" fill="#000"/></svg>
|
After Width: | Height: | Size: 341 B |
1
docs/r/icons/font-size.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.245 12l.37-1.084h1.95L4.935 12h1.052L4.11 6.91H3.068L1.191 12h1.054zM3.56 8.147h.06l.671 1.964H2.89l.671-1.964zM8.415 12l.822-2.335h3.64L13.698 12h1.108l-3.205-8.727h-1.09L7.306 12h1.108zm2.59-7.347h.103l1.436 4.074H9.57l1.436-4.074z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 341 B |
1
docs/r/icons/letter-spacing-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.415 12l.822-2.335h3.64L10.698 12h1.108L8.602 3.273h-1.09L4.306 12h1.108zm2.59-7.347h.103l1.436 4.074H6.57l1.436-4.074z" fill="#000"/><path fill-rule="evenodd" clip-rule="evenodd" d="M0 14V2h1v12H0zm15 0V2h1v12h-1z" fill="#000"/></svg>
|
After Width: | Height: | Size: 321 B |
1
docs/r/icons/letter-spacing.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.415 12l.822-2.335h3.64L10.698 12h1.108L8.602 3.273h-1.09L4.306 12h1.108zm2.59-7.347h.103l1.436 4.074H6.57l1.436-4.074z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M0 14V2h1v12H0zm15 0V2h1v12h-1z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 321 B |
1
docs/r/icons/line-height-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.297 12l.762-2.14h3.32L10.14 12h1.015L8.22 4h-1l-2.94 8h1.016zm1.066-3l1.324-3.734h.063L9.074 9h-2.71z" fill="#000"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2H1V1h14v1zm0 13H1v-1h14v1z" fill="#000"/></svg>
|
After Width: | Height: | Size: 304 B |
1
docs/r/icons/line-height.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.297 12l.762-2.14h3.32L10.14 12h1.015L8.22 4h-1l-2.94 8h1.016zm1.066-3l1.324-3.734h.063L9.074 9h-2.71z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2H1V1h14v1zm0 13H1v-1h14v1z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 304 B |
3
docs/r/icons/minimize-black.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="8" r="2" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 146 B |
3
docs/r/icons/minimize.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="8" r="2" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 146 B |
1
docs/r/icons/popup-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.293l3.354 3.353-.707.708L8 4.707 5.354 7.354l-.708-.708L8 3.293zm0 8L5.354 8.646l-.708.708L8 12.707l3.354-3.353-.707-.708L8 11.293z" fill="#000"/></svg>
|
After Width: | Height: | Size: 281 B |
1
docs/r/icons/popup.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.293l3.354 3.353-.707.708L8 4.707 5.354 7.354l-.708-.708L8 3.293zm0 8L5.354 8.646l-.708.708L8 12.707l3.354-3.353-.707-.708L8 11.293z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 281 B |
1
docs/r/icons/reset-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.993.893L6.95 2.817l1.272.187A6 6 0 112 9h1a5 5 0 105.928-4.914l-.005.032-.79-.116A5.078 5.078 0 008 4v-.018L6.684 3.79l2.214 2.908-.796.606-3.287-4.319L9.459.047l.534.846z" fill="#000"/></svg>
|
After Width: | Height: | Size: 279 B |
1
docs/r/icons/reset.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.993.893L6.95 2.817l1.272.187A6 6 0 112 9h1a5 5 0 105.928-4.914l-.005.032-.79-.116A5.078 5.078 0 008 4v-.018L6.684 3.79l2.214 2.908-.796.606-3.287-4.319L9.459.047l.534.846z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 279 B |
1
docs/r/icons/settings-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H6V3h8v1zM4 4H2V3h2v1zm10 3H6V6h8v1zM4 7H2V6h2v1zm10 3H6V9h8v1zM4 10H2V9h2v1zm10 3H6v-1h8v1zM4 13H2v-1h2v1z" fill="#000"/></svg>
|
After Width: | Height: | Size: 257 B |
1
docs/r/icons/settings.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H6V3h8v1zM4 4H2V3h2v1zm10 3H6V6h8v1zM4 7H2V6h2v1zm10 3H6V9h8v1zM4 10H2V9h2v1zm10 3H6v-1h8v1zM4 13H2v-1h2v1z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 257 B |
1
docs/r/icons/style-black.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 13V3h1v10H0zm3 0V3h2v10H3zm4 0V3h3v10H7zm5 0V3h4v10h-4z" fill="#000"/></svg>
|
After Width: | Height: | Size: 203 B |
1
docs/r/icons/style.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 13V3h1v10H0zm3 0V3h2v10H3zm4 0V3h3v10H7zm5 0V3h4v10h-4z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 203 B |
1
docs/r/popup.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.293l3.354 3.353-.708.708L8 4.707 5.354 7.354l-.708-.708L8 3.293zm0 8L5.354 8.646l-.708.708L8 12.707l3.354-3.353-.708-.708L8 11.293z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 281 B |
1
docs/r/reset.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.993.893L6.95 2.817l1.272.187A6 6 0 112 9h1a5 5 0 105.928-4.914l-.005.032-.79-.116A5.078 5.078 0 008 4v-.018L6.684 3.79l2.214 2.908-.796.606-3.287-4.319L9.459.047l.534.846z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 279 B |
1
docs/r/settings.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H6V3h8v1zM4 4H2V3h2v1zm10 3H6V6h8v1zM4 7H2V6h2v1zm10 3H6V9h8v1zM4 10H2V9h2v1zm10 3H6v-1h8v1zM4 13H2v-1h2v1z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 257 B |
1
docs/r/weights-and-styles.svg
Normal file
After Width: | Height: | Size: 230 KiB |