HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
Any URLs added here will be added as <link>
s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
Any URL's added here will be added as <script>
s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
Search for and use JavaScript packages from npm here. By selecting a package, an import
statement will be added to the top of the JavaScript editor for this package.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
- var languages=[{id:1,name:"js"},{id:2,name:"java"},{id:3,name:"python"},{id:4,name:"dart"},{id:5,name:"scala"},{id:6,name:"kotlin"}];
- var tableColumns = ['#', 'nickname', 'wins', 'games']
- var tableData=[{nickname:"rockberry",wins:8,games:9},{nickname:"pickerman",wins:7,games:10},{nickname:"freez_1989",wins:6,games:11},{nickname:"monjuik",wins:4,games:5},{nickname:"AIncolsh",wins:4,games:6},{nickname:"n00bmaster69",wins:3,games:3},{nickname:"ヽ(ಠل͜ಠ)ノ",wins:2,games:4},{nickname:"pro100",wins:1,games:1},{nickname:"kenobi",wins:1,games:1},{nickname:"assassin300",wins:1,games:1}];
- var testsResult = '00:02 +0: test\n00:02 +0: test\nSome local output for testssssss\nHere we try to check if pin code `1` is correct\n-----------------\n00:02 +0 -1: test [E]\nExpected: <false>\nActual: <true>\npackage:test_api expect\ntest/test1.dart 5:19 main.<fn>\nSome local output for testssssss\nHere we try to check if pin code `12` is correct\n-----------------\n00:02 +0 -2: test [E]\nExpected: <false>\nActual: <true>\npackage:test_api expect\ntest/test1.dart 6:19 main.<fn>\nSome local output for testssssss\nHere we try to check if pin code `123` is correct\n-----------------\n00:02 +0 -3: test [E]\nExpected: <false>\nActual: <true>\npackage:test_api expect\ntest/test1.dart 7:19 main.<fn>\nSome local output for testssssss\nHere we try to check if pin code `12345` is correct';
- var editorCode = 'def validate_pin(pin):\n return len(pin) in (4, 6) and all(p in "0123456789" for p in pin)';
mixin logo(className)
svg(
class= className
width="87" viewbox="0 0 87 58")
path(
fill="#ffffff"
fill-rule="evenodd"
d="M7 54.39A4.99 4.99 0 0011.82 58c1.3 0 2.5-.38 3.4-1.2v.89h2.19V43.85l-2.5 2.54V47a5.38 5.38 0 00-.38-.24l-1.6 1.62c.58.12 1.1.4 1.46.84.56.7.8 1.74.8 2.8a4.4 4.4 0 01-.8 2.8c-.54.62-1.3.92-2.2.92-.87 0-1.74-.32-2.26-1.1a4.66 4.66 0 01-.62-2.6L7 54.4zm18.9-19.13a5.79 5.79 0 004.04 1.54c1.03 0 2.13-.32 2.98-.86a5.31 5.31 0 001.97-2.37l-2.47-.75a2.71 2.71 0 01-2.6 1.61c-.87 0-1.65-.32-2.17-.94l-1.75 1.77zm3.68-3.72h5.43c.13-1.74-.1-3.3-.95-4.54l-1.7 1.73c.08.25.12.52.15.82h-.96l-1.97 1.99zm42.35 10.75v15.4h2.49v-15.4h-2.49zM21.88 52.74c.06.67.23 1.34.62 1.84.52.7 1.35 1.05 2.26 1.05a2.71 2.71 0 002.61-1.61l2.46.75c-.39.95-1.1 1.8-1.96 2.37-.85.55-1.95.86-2.98.86a5.62 5.62 0 01-4.35-1.89 6.27 6.27 0 01-1.35-3.96c0-1.6.44-3.12 1.35-4.23a5.37 5.37 0 014.22-1.86c1.64 0 2.96.54 3.98 1.78 1.07 1.3 1.36 3 1.22 4.9h-8.08zm.64-3.46c.6-.75 1.41-1.02 2.24-1.02.85 0 1.68.31 2.18.94.33.46.47.96.51 1.55h-5.53c.09-.54.27-1.03.6-1.47zm18.72-1.42a6.82 6.82 0 011.29 4.17 6.6 6.6 0 01-1.29 4.17 4.99 4.99 0 01-3.87 1.8c-1.3 0-2.48-.38-3.37-1.17v.86h-2.22V42.6h2.5V47a5.27 5.27 0 016.96.86zm-1.36 4.17c0 1-.17 1.97-.62 2.62A2.62 2.62 0 0137 55.74c-.9 0-1.66-.3-2.2-.92a4.4 4.4 0 01-.8-2.8c0-1.06.24-2.1.8-2.8.5-.6 1.27-.9 2.12-.9.97 0 1.78.31 2.3 1.09.45.65.66 1.6.66 2.62zm13.66 5.66h-2.17v-1.5c-1.1 1.37-2.24 1.81-4 1.81-2.23 0-3.68-1.36-3.68-3.48 0-1.46.56-2.55 1.96-3.22 1.19-.55 3-.8 4.55-1.01l.86-.13c-.15-1.06-.95-1.71-2.34-1.71-1.12 0-2.11.37-2.9 1.17l-1.47-1.68a6.03 6.03 0 014.58-1.88c1.2 0 2.4.5 3.19 1.2 1.07.91 1.42 2.21 1.42 3.62v6.8zm-2.46-5.54c0 .8 0 1.6-.4 2.27a3.15 3.15 0 01-2.73 1.46c-1.03 0-1.8-.65-1.8-1.55 0-.88.85-1.36 1.84-1.57.98-.23 2.12-.44 3.09-.6zm15.65-3.8v4.89c0 .74 0 1.34.23 1.72.27.46.77.65 1.22.7.56.04 1.25 0 1.85-.09v2.12a8.4 8.4 0 01-3.07.08c-1.01-.17-1.68-.52-2.23-1.43-.5-.76-.5-1.7-.48-2.77V48.34H59V53.24c0 .74 0 1.34.23 1.72.27.46.76.65 1.22.7.56.04 1.24 0 1.84-.09v2.12a8.4 8.4 0 01-3.06.08 2.95 2.95 0 01-2.26-1.43c-.48-.75-.47-1.68-.46-2.76v-5.24H54.5v-1.97h2.03v-3.14H59v3.14h5.24v-3.14h2.48v3.14h3.3v1.97h-3.3zm12.16 4.4c.06.66.23 1.33.62 1.83.52.7 1.35 1.05 2.26 1.05a2.71 2.71 0 002.6-1.61l2.47.75c-.4.95-1.1 1.8-1.97 2.37-.85.55-1.94.86-2.98.86a5.62 5.62 0 01-4.35-1.89 6.27 6.27 0 01-1.34-3.96c0-1.6.43-3.12 1.34-4.23a5.37 5.37 0 014.23-1.86c1.63 0 2.96.54 3.97 1.78 1.08 1.3 1.37 3 1.23 4.9h-8.08zm.64-3.47c.6-.75 1.4-1.02 2.24-1.02.85 0 1.67.31 2.17.94.33.46.48.96.52 1.55h-5.53c.08-.54.27-1.03.6-1.47zM52 6.59a5 5 0 00-4.73-2.89c-1.68 0-3.26.64-4.29 1.88a6.61 6.61 0 00-1.37 4.25c0 1.43.45 2.84 1.37 3.98.27.33.59.62.95.86l1.76-1.76a2.51 2.51 0 01-.71-.64 3.5 3.5 0 01-.63-1.85h3.83L52 6.59zm-25.46 25.5l-2.1 2.1a7.15 7.15 0 01-.67-3.19 6.8 6.8 0 011.3-4.19 5.4 5.4 0 017.06-.86v-4.42h2.55v2.4l-3.7 3.72a3.02 3.02 0 00-1.51-.37c-1 0-1.81.31-2.34 1.1-.46.64-.67 1.59-.67 2.62 0 .37.02.74.08 1.09zM28.96 0h-2.52v2.34h2.52V0zm-6 3.73a4.1 4.1 0 011.78.29v2.36a4.74 4.74 0 00-2.04-.3c-.84.07-1.5.36-1.91.8-.66.68-.84 1.56-.84 2.61v5.9H17.4V4.02h2.25V5.6c.27-.46.65-.89 1.14-1.2.65-.44 1.4-.65 2.16-.67zm-9.42.29h2.48l-3.47 11.37h-2.13L8.01 7.56l-2.57 7.83H3.47L0 3.99l2.5.03 2.23 7.28 2.23-7.28h2.12l2.25 7.28 2.2-7.28zm12.9 0h2.52v11.37h-2.52V4.02zm7.75 11.37v-4.61h1.33l3.28 4.6h2.9l-4.12-5.8 3.76-5.56H38.5L35.52 8.4h-1.33V.23h-2.56l-.02 15.16h2.59zM45 6.95a2.78 2.78 0 012.28-1.04c.86 0 1.7.32 2.2.95.34.46.49.97.53 1.56h-5.61c.08-.55.27-1.03.6-1.47zM10.62 28.62l-2.52.7a2.9 2.9 0 00-.94-1.41c-.47-.36-1.01-.53-1.58-.53-.93 0-1.68.34-2.19 1.03-.54.7-.69 1.64-.69 2.6 0 .92.15 1.86.7 2.56.5.7 1.25 1.05 2.18 1.05.57 0 1.16-.12 1.62-.5.44-.36.67-.78.84-1.29l2.58.57a5.2 5.2 0 01-1.82 2.67c-1 .7-1.85.93-3.22.93-1.85 0-3.22-.59-4.2-1.87A6.38 6.38 0 010 31c0-1.58.42-2.99 1.37-4.12A5.09 5.09 0 015.59 25c1.2 0 2 .17 2.94.76a4.54 4.54 0 012.08 2.86zM16.94 37a5.5 5.5 0 01-4.29-1.9A6.25 6.25 0 0111.3 31c0-1.58.44-3 1.36-4.12A5.55 5.55 0 0116.94 25a5.5 5.5 0 014.29 1.88A6.26 6.26 0 0122.59 31c0 1.58-.4 2.9-1.36 4.1a5.46 5.46 0 01-4.29 1.9zm2.27-8.59c.53.7.71 1.64.71 2.6 0 .92-.18 1.86-.71 2.56-.5.7-1.37 1.05-2.27 1.05-.92 0-1.77-.36-2.27-1.05-.55-.7-.7-1.64-.7-2.57 0-.95.15-1.9.7-2.59.5-.7 1.35-1.03 2.27-1.03.9 0 1.77.34 2.27 1.03z")
path(
stroke="#d73739"
stroke-width="2"
d="M55 5L4 56")
.app
//- intro screen
.app__screen.intro
svg.intro__logo(width="87" viewbox="0 0 87 58")
defs
//- ⚠️TODO: animation works unstable in Safari
filter#glitch-filter
feflood(flood-color="black" result="black")
feflood(flood-color="red" result="flood1")
feflood(flood-color="limegreen" result="flood2")
feoffset(in="SourceGraphic" dx="3" dy="0" result="off1a")
feoffset(in="SourceGraphic" dx="2" dy="0" result="off1b")
feoffset(in="SourceGraphic" dx="-3" dy="0" result="off2a")
feoffset(in="SourceGraphic" dx="-2" dy="0" result="off2b")
fecomposite(in="flood1" in2="off1a" operator="in" result="comp1")
fecomposite(in="flood2" in2="off2a" operator="in" result="comp2")
femerge(x="0" width="100%" result="merge1")
femergenode(in="black")
femergenode(in="comp1")
femergenode(in="off1b")
animate(attributename="y" dur="3s" repeatcount="indefinite" values="65; 65; 18; 65; 18; 1; 1; 31; 25; 65; 65; 12; 42; 25; 65; 25; 43; 6; 18; 65; 63;" keytimes="0; .362; .368; .421; .440; .477; .518; .564; .593; .613; .644; .693; .721; .736; .772; .818; .844; .894; .925; .939; 1")
animate(attributename="height" dur="3s" repeatcount="indefinite" values="10; 0; 10; 30; 50; 0; 10; 0; 0; 0; 10; 50; 40; 0; 0; 0; 40; 30; 10; 0; 50" keytimes="0; .362; .368; .421; .440; .477; .518; .564; .593; .613; .644; .693; .721; .736; .772; .818; .844; .894; .925; .939; 1")
femerge(result="merge2" x="0" y="48" width="100%" height="52")
femergenode(in="black")
femergenode(in="comp2")
femergenode(in="off2b")
animate(attributename="y" dur="3s" repeatcount="indefinite" values="57; 57; 38; 29; 23; 57; 43; 49; 53; 55; 37; 27; 53; 36; 48; 23; 7; 55; 55; 57; 56;" keytimes="0; .055; .100; .125; .159; .182; .202; .236; .268; .326; .357; .400; .408; .461; .493; .513; .548; .577; .613; 1")
animate(attributename="height" dur="3s" repeatcount="indefinite" values="0; 0; 0; 16; 16; 12; 12; 0; 0; 5; 10; 22; 33; 11; 0; 0; 10;" keytimes="0; .055; .100; .125; .159; .182; .202; .236; .268; .326; .357; .400; .408; .461; .493; .513; 1")
femerge
femergenode(in="SourceGraphic")
femergenode(in="merge1")
femergenode(in="merge2")
g
path(filter="url(#glitch-filter)" fill="#ffffff" fill-rule="evenodd" d="M7 54.39A4.99 4.99 0 0011.82 58c1.3 0 2.5-.38 3.4-1.2v.89h2.19V43.85l-2.5 2.54V47a5.38 5.38 0 00-.38-.24l-1.6 1.62c.58.12 1.1.4 1.46.84.56.7.8 1.74.8 2.8a4.4 4.4 0 01-.8 2.8c-.54.62-1.3.92-2.2.92-.87 0-1.74-.32-2.26-1.1a4.66 4.66 0 01-.62-2.6L7 54.4zm18.9-19.13a5.79 5.79 0 004.04 1.54c1.03 0 2.13-.32 2.98-.86a5.31 5.31 0 001.97-2.37l-2.47-.75a2.71 2.71 0 01-2.6 1.61c-.87 0-1.65-.32-2.17-.94l-1.75 1.77zm3.68-3.72h5.43c.13-1.74-.1-3.3-.95-4.54l-1.7 1.73c.08.25.12.52.15.82h-.96l-1.97 1.99zm42.35 10.75v15.4h2.49v-15.4h-2.49zM21.88 52.74c.06.67.23 1.34.62 1.84.52.7 1.35 1.05 2.26 1.05a2.71 2.71 0 002.61-1.61l2.46.75c-.39.95-1.1 1.8-1.96 2.37-.85.55-1.95.86-2.98.86a5.62 5.62 0 01-4.35-1.89 6.27 6.27 0 01-1.35-3.96c0-1.6.44-3.12 1.35-4.23a5.37 5.37 0 014.22-1.86c1.64 0 2.96.54 3.98 1.78 1.07 1.3 1.36 3 1.22 4.9h-8.08zm.64-3.46c.6-.75 1.41-1.02 2.24-1.02.85 0 1.68.31 2.18.94.33.46.47.96.51 1.55h-5.53c.09-.54.27-1.03.6-1.47zm18.72-1.42a6.82 6.82 0 011.29 4.17 6.6 6.6 0 01-1.29 4.17 4.99 4.99 0 01-3.87 1.8c-1.3 0-2.48-.38-3.37-1.17v.86h-2.22V42.6h2.5V47a5.27 5.27 0 016.96.86zm-1.36 4.17c0 1-.17 1.97-.62 2.62A2.62 2.62 0 0137 55.74c-.9 0-1.66-.3-2.2-.92a4.4 4.4 0 01-.8-2.8c0-1.06.24-2.1.8-2.8.5-.6 1.27-.9 2.12-.9.97 0 1.78.31 2.3 1.09.45.65.66 1.6.66 2.62zm13.66 5.66h-2.17v-1.5c-1.1 1.37-2.24 1.81-4 1.81-2.23 0-3.68-1.36-3.68-3.48 0-1.46.56-2.55 1.96-3.22 1.19-.55 3-.8 4.55-1.01l.86-.13c-.15-1.06-.95-1.71-2.34-1.71-1.12 0-2.11.37-2.9 1.17l-1.47-1.68a6.03 6.03 0 014.58-1.88c1.2 0 2.4.5 3.19 1.2 1.07.91 1.42 2.21 1.42 3.62v6.8zm-2.46-5.54c0 .8 0 1.6-.4 2.27a3.15 3.15 0 01-2.73 1.46c-1.03 0-1.8-.65-1.8-1.55 0-.88.85-1.36 1.84-1.57.98-.23 2.12-.44 3.09-.6zm15.65-3.8v4.89c0 .74 0 1.34.23 1.72.27.46.77.65 1.22.7.56.04 1.25 0 1.85-.09v2.12a8.4 8.4 0 01-3.07.08c-1.01-.17-1.68-.52-2.23-1.43-.5-.76-.5-1.7-.48-2.77V48.34H59V53.24c0 .74 0 1.34.23 1.72.27.46.76.65 1.22.7.56.04 1.24 0 1.84-.09v2.12a8.4 8.4 0 01-3.06.08 2.95 2.95 0 01-2.26-1.43c-.48-.75-.47-1.68-.46-2.76v-5.24H54.5v-1.97h2.03v-3.14H59v3.14h5.24v-3.14h2.48v3.14h3.3v1.97h-3.3zm12.16 4.4c.06.66.23 1.33.62 1.83.52.7 1.35 1.05 2.26 1.05a2.71 2.71 0 002.6-1.61l2.47.75c-.4.95-1.1 1.8-1.97 2.37-.85.55-1.94.86-2.98.86a5.62 5.62 0 01-4.35-1.89 6.27 6.27 0 01-1.34-3.96c0-1.6.43-3.12 1.34-4.23a5.37 5.37 0 014.23-1.86c1.63 0 2.96.54 3.97 1.78 1.08 1.3 1.37 3 1.23 4.9h-8.08zm.64-3.47c.6-.75 1.4-1.02 2.24-1.02.85 0 1.67.31 2.17.94.33.46.48.96.52 1.55h-5.53c.08-.54.27-1.03.6-1.47zM52 6.59a5 5 0 00-4.73-2.89c-1.68 0-3.26.64-4.29 1.88a6.61 6.61 0 00-1.37 4.25c0 1.43.45 2.84 1.37 3.98.27.33.59.62.95.86l1.76-1.76a2.51 2.51 0 01-.71-.64 3.5 3.5 0 01-.63-1.85h3.83L52 6.59zm-25.46 25.5l-2.1 2.1a7.15 7.15 0 01-.67-3.19 6.8 6.8 0 011.3-4.19 5.4 5.4 0 017.06-.86v-4.42h2.55v2.4l-3.7 3.72a3.02 3.02 0 00-1.51-.37c-1 0-1.81.31-2.34 1.1-.46.64-.67 1.59-.67 2.62 0 .37.02.74.08 1.09zM28.96 0h-2.52v2.34h2.52V0zm-6 3.73a4.1 4.1 0 011.78.29v2.36a4.74 4.74 0 00-2.04-.3c-.84.07-1.5.36-1.91.8-.66.68-.84 1.56-.84 2.61v5.9H17.4V4.02h2.25V5.6c.27-.46.65-.89 1.14-1.2.65-.44 1.4-.65 2.16-.67zm-9.42.29h2.48l-3.47 11.37h-2.13L8.01 7.56l-2.57 7.83H3.47L0 3.99l2.5.03 2.23 7.28 2.23-7.28h2.12l2.25 7.28 2.2-7.28zm12.9 0h2.52v11.37h-2.52V4.02zm7.75 11.37v-4.61h1.33l3.28 4.6h2.9l-4.12-5.8 3.76-5.56H38.5L35.52 8.4h-1.33V.23h-2.56l-.02 15.16h2.59zM45 6.95a2.78 2.78 0 012.28-1.04c.86 0 1.7.32 2.2.95.34.46.49.97.53 1.56h-5.61c.08-.55.27-1.03.6-1.47zM10.62 28.62l-2.52.7a2.9 2.9 0 00-.94-1.41c-.47-.36-1.01-.53-1.58-.53-.93 0-1.68.34-2.19 1.03-.54.7-.69 1.64-.69 2.6 0 .92.15 1.86.7 2.56.5.7 1.25 1.05 2.18 1.05.57 0 1.16-.12 1.62-.5.44-.36.67-.78.84-1.29l2.58.57a5.2 5.2 0 01-1.82 2.67c-1 .7-1.85.93-3.22.93-1.85 0-3.22-.59-4.2-1.87A6.38 6.38 0 010 31c0-1.58.42-2.99 1.37-4.12A5.09 5.09 0 015.59 25c1.2 0 2 .17 2.94.76a4.54 4.54 0 012.08 2.86zM16.94 37a5.5 5.5 0 01-4.29-1.9A6.25 6.25 0 0111.3 31c0-1.58.44-3 1.36-4.12A5.55 5.55 0 0116.94 25a5.5 5.5 0 014.29 1.88A6.26 6.26 0 0122.59 31c0 1.58-.4 2.9-1.36 4.1a5.46 5.46 0 01-4.29 1.9zm2.27-8.59c.53.7.71 1.64.71 2.6 0 .92-.18 1.86-.71 2.56-.5.7-1.37 1.05-2.27 1.05-.92 0-1.77-.36-2.27-1.05-.55-.7-.7-1.64-.7-2.57 0-.95.15-1.9.7-2.59.5-.7 1.35-1.03 2.27-1.03.9 0 1.77.34 2.27 1.03z")
path(stroke="#d73739" stroke-width="2" d="M55 5L4 56")
//- board screen
.app__screen.board(hidden)
//- header
header.board__header.board-header
button.board-header__back-button(
id="boardBackButton"
type="button"
aria-label="back to leaderboard")
svg(
width="16" height="16" viewbox="0 0 448 512"
aria-hidden="true")
path(
d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z")
.board-header__center
+logo("board-header__logo")
.board-header__loading-tooltip.loading-tooltip
.loading-tooltip__text Waiting for the second battler
.loading-tooltip__dots
.loading-tooltip__dot
.loading-tooltip__dot
.loading-tooltip__dot
button.board-header__start-button.button(
id="boardStartButton"
type="button") Start game
//- content
.board__content
//- loader
svg.board__loader.board-loader(
viewBox="0 0 1439 204"
fill="none"
aria-hidden="true")
path.board-loader__line(
d="M1 119l5-5c18-15 44-15 62 0v0c18 16 47 15 64-3l31-32c25-26 68-23 89 6l36 47c20 28 60 32 86 9l33-28c25-23 65-19 85 8l45 59c27 35 82 29 100-11l61-129c19-41 75-46 102-9l99 140c24 33 74 33 97-1l26-37c22-32 67-34 93-5l8 9c24 28 68 27 91-2l88-112c22-29 65-30 90-3l46 51")
//- leaderboard
.board__content-item.board__content-leaderboard
table.board__leaderboard.leaderboard(
aria-label="leaderboard")
thead
tr
each cell in tableColumns
th= cell
tbody
each cell, index in tableData
tr
td
if (index + 1) < 10
| 0
| #{index + 1}
td= cell.nickname
td
if cell.wins < 10
| 0
| #{cell.wins}
td
if cell.games < 10
| 0
| #{cell.games}
//- login
.board__content-item.board__content-login
form.board__login.login(
aria-label="login")
input.login__field.input(
id="boardNicknameInput"
placeholder="nickname"
value="pickerman"
aria-label="nickname")
input.login__field.input(
type="password"
value="password"
placeholder="password"
aria-label="password")
select.login__field.select(
aria-label="language")
option(
value=""
disabled) language
each language in languages
option(
value= language.id
selected= language.id === 3)= language.name
button.login__button.button(
id="boardStartLoginButton"
type="button") Start
//- footer
footer.board__footer
ul.languages-list(
aria-label="programming languages")
- var languagesListMiddle = languages.length / 2 | 0;
each language, index in languages
li.languages-list__item= language.name
if index == languagesListMiddle - 1
li.languages-list__item.languages-list__item--cross(
aria-hidden="true")
//- countdown screen
.app__screen.countdown(
hidden)
.countdown__container
.countdown__timer.countdown-timer
.countdown-timer__rotator
- var n = 5;
while n >= 0
.countdown-timer__item= n--
svg.countdown__indicator(
viewBox="0 0 576 576")
circle.countdown__circle.countdown__indicator-placeholder
circle.countdown__circle.countdown__indicator-loader
//- challenge screen
.app__screen.challenge(
hidden)
//- header
header.challenge__header.challenge-header
+logo("challenge-header__logo")
ul.challenge-header__languages-list.languages-list(
aria-label="programming languages")
each language, index in languages
li.languages-list__item(
class= index == 2 ? "languages-list__item--active" : null)= language.name
.challenge-header__timer
span.visually-hidden time remaining:
| 05:20
button.challenge-header__button.button(
id="challengeCheckButton") Check
pre.challenge__editor(
contenteditable="true"
spellcheck="false")= editorCode
.challenge__info.challenge-info
//- TODO: role="tablist"
.challenge-info__tabs.tabs
button.tabs__button.tabs__button--active(
data-id="challengeTask") Task
button.tabs__button(
data-id="challengeResult") Result
.challenge-info__content.tabs-content
.tabs-content__wrapper
.tabs-content__container
section.tabs-content__item.tabs-content__item--active(
id="challengeTask")
h2 PIN code check
p Write a function to check the PIN code. PIN code can contain 4 or 6 digits. If the PIN code is correct, it should return <code>true</code>, if it is incorrect, <code>false</code>.
section.tabs-content__item.tabs-content__item--results(
id="challengeResult")
h2 Tests didn't passed
pre= testsResult
//- finish screen
.app__screen.finish.finish--victory(
hidden)
+logo("finish__logo")
.finish__content.finish-content
h1.finish-content__heading You are the champion!
p.finish-content__text It's a goddamn victory!
button.finish-content__button.button(
id="finishCompleteButton") Complete
/* --- variables --- */
$bg: black;
$bg-victory: rgb(16 144 94 / 64%);
$bg-defeat: rgb(142 16 16 / 64%);
$color-primary: #4488ff;
$color-secondary: #d73739;
$color-text-primary: rgb(255 255 255);
$color-text-secondary: rgb(255 255 255 / 32%);
$breakpoint: 48em;
$font-primary: "PT Mono", monospace;
$font-secondary: "Manrope", sans-serif;
$fontWeight-normal: 400;
$fontWeight-bold: 700;
$borderColor: rgb(255 255 255 / 16%);
$borderColor-hover: rgb(255 255 255 / 56%);
$outlineWidth: .25rem;
$outlineOffset: .25em;
$outlineColor: $color-primary;
$controlHeight: 3em;
$controlFontSize: 1rem;
$controlLineHeight: 1.25;
$controlLineBox: $controlFontSize * $controlLineHeight;
$controlBorderWidth: .063em;
$controlBorderColor: $borderColor;
$layoutPadding: 1rem;
$layoutPadding-large: 3.5rem;
$screenAnimationDuration: .5s;
/* --- base --- */
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;700&family=PT+Mono&display=swap");
:root {
font-size: 90%;
color-scheme: dark;
@media (min-width: $breakpoint) {
font-size: 100%;
}
}
*,
::before,
::after {
box-sizing: border-box;
}
:focus:not(.focus-visible) {
outline: none;
}
.focus-visible {
outline: $outlineWidth dotted $outlineColor;
outline-offset: $outlineOffset;
}
[hidden] {
display: none !important;
}
/* --- utilities --- */
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
border: 0 !important;
overflow: hidden !important;
white-space: nowrap !important;
clip: rect(0, 0, 0, 0) !important;
}
/* --- layout --- */
html {
height: 100%;
}
body {
display: grid;
grid-template-rows: minmax(0, 1fr);
height: 100%;
margin: 0;
color: $color-text-primary;
font-family: $font-primary;
background-color: $bg;
font-size: 88%;
@media (min-width: $breakpoint) {
font-size: 100%;
}
}
/* --- controls --- */
.button,
.input,
.select {
margin: 0;
font-size: 1rem;
font-family: inherit;
background: none;
}
.button {
$paddingV: calc((#{$controlHeight} - (#{$controlFontSize} * #{$controlLineHeight}) - (#{$controlBorderWidth} * 2)) / 2);
position: relative;
min-height: $controlHeight;
padding: $paddingV 1.5em;
border: $controlBorderWidth solid;
color: $color-primary;
line-height: 1.25;
cursor: pointer;
user-select: none;
&:hover,
&:active {
border-color: $borderColor-hover;
color: $color-text-primary;
}
&:active {
top: .063em;
}
}
.input {
height: $controlHeight;
border: none;
border-bottom: $controlBorderWidth solid $controlBorderColor;
color: $color-text-primary;
caret-color: $color-primary;
&::placeholder {
color: $color-text-secondary;
opacity: 1;
}
&:hover {
border-color: $borderColor-hover;
}
&:focus {
border-color: $color-primary;
}
&.focus-visible {
outline: none;
}
}
.select {
$bgSize: 2em;
$paddingRight: $bgSize + .5em;
height: $controlHeight;
padding-right: $paddingRight;
border: none;
border-bottom: $controlBorderWidth solid $controlBorderColor;
color: $color-text-primary;
background-color: rgb(255 255 255 / 0); // for FF
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path opacity='.32' stroke='%23fff' d='M10 13l6 6 6-6'/></svg>");
background-repeat: no-repeat;
background-position: right;
background-size: $bgSize;
appearance: none;
&:hover {
border-color: $borderColor-hover;
}
&:focus {
border-color: $color-primary;
}
&.focus-visible {
outline: none;
}
}
/* --- app --- */
.app {
height: 100%;
}
.app__screen {
height: 100%;
}
@keyframes screenSlideLeft {
from {
opacity: 0;
transform: translateX(-2rem);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes screenSlideUp {
from {
opacity: 0;
transform: translateY(2rem);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes screenSlideDown {
from {
opacity: 0;
transform: translateY(-2rem);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes screenFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* ------ INTRO SCREEN ------ */
.intro {
display: grid;
place-items: center;
}
.intro__logo {
width: 12rem;
}
/* ------ BOARD SCREEN ------ */
.board {
display: grid;
grid-template-rows: auto 1fr auto;
row-gap: 1rem;
animation: screenSlideUp $screenAnimationDuration;
@media (min-width: $breakpoint) {
row-gap: 4rem;
}
}
.board__content {
position: relative;
display: flex;
overflow: hidden auto;
}
.board__content-item {
flex-shrink: 0;
display: grid;
place-items: center;
width: 100%;
padding: 0 $layoutPadding;
transition-property: visibility, opacity, transform;
transition-duration: .5s;
transition-timing-function: ease;
@media (min-width: $breakpoint) {
padding: 0 $layoutPadding-large;
}
}
.board__content-leaderboard {
// screen state
.board--login & {
visibility: hidden;
opacity: 0;
transform: translateX(-100%);
}
}
.board__content-login {
// screen state
.board--login & {
visibility: visible;
opacity: 1;
transform: translateX(-100%);
}
.board:not(.board--login) & {
visibility: hidden;
opacity: 0;
}
}
.board__leaderboard {
width: 100%;
max-width: 40rem;
}
.board__leaderboard-table {
width: 100%;
}
.board__login {
width: 100%;
max-width: 24rem;
}
.board__loader {
position: fixed;
top: 50%;
left: 50%;
z-index: -1;
width: 100%;
transform: translate(-50%, -50%);
// screen state
.board:not(.board--waiting) & {
display: none;
}
}
.board__footer {
display: flex;
justify-content: center;
padding: 0 $layoutPadding $layoutPadding;
@media (min-width: $breakpoint) {
padding: 0 $layoutPadding-large 1.5rem;
}
}
/* --- header --- */
.board-header {
display: grid;
grid-template: "left center right" / 25% 1fr 25%;
column-gap: 1rem;
align-items: center;
padding: $layoutPadding $layoutPadding 0;
@media (min-width: $breakpoint) {
padding: $layoutPadding-large $layoutPadding-large 0;
}
}
.board-header__back-button {
grid-area: left;
justify-self: start;
display: inline-grid;
place-items: center;
padding: .5rem;
border: none;
border-radius: 50%;
color: $color-text-primary;
background: none;
cursor: pointer;
user-select: none;
&:hover {
background-color: rgb(255 255 255 / 8%);
}
svg {
$size: 1.5rem;
width: $size;
height: $size;
fill: currentcolor;
}
.board:not(.board--login) & {
display: none;
}
}
.board-header__center {
grid-area: center;
display: grid;
place-items: center;
}
.board-header__logo {
// screen state
.board--waiting & {
display: none;
}
}
.board-header__loading-tooltip {
// screen state
.board:not(.board--waiting) & {
display: none;
}
}
.board-header__start-button {
grid-area: right;
justify-self: end;
// screen state
.board--login &,
.board--waiting & {
display: none;
}
}
/* --- loading tooltip --- */
.loading-tooltip {
display: grid;
row-gap: 1em;
text-align: center;
justify-items: center;
animation: loadingTooltip .5s; // TODO
@keyframes loadingTooltip {
from {
opacity: 0;
transform: translateY(2em);
}
to {
opacity: 1;
transform: translateY(0);
}
}
}
.loading-tooltip__text {
position: relative;
padding: .25em .75em;
border-radius: .5em;
line-height: 1.5;
background-color: rgb(255 255 255 / 8%);
&::after {
$size: .5em;
content: "";
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
margin-bottom: -$size;
margin-left: -$size;
border: $size solid transparent;
border-top-color: rgb(255 255 255 / 8%);
border-bottom: 0;
}
}
.loading-tooltip__dots {
display: flex;
column-gap: .25em;
}
.loading-tooltip__dot {
$size: .25em;
width: $size;
height: $size;
border-radius: 50%;
background-color: $color-secondary;
animation: tooltipDots 2s infinite ease-in-out;
@for $i from 1 through 3 {
&:nth-child(#{$i}) {
animation-delay: $i * .25s;
}
}
@keyframes tooltipDots {
20% {
transform: translateY(-.125em);
}
40% {
transform: translateY(0);
}
}
}
/* --- loader --- */
.board-loader__line {
$dash: 2000;
filter: drop-shadow(0 0 .5rem $color-secondary);
animation: loaderLine 3s linear infinite; // TODO
stroke: $color-secondary;
stroke-dasharray: $dash;
stroke-dashoffset: $dash;
stroke-width: .125rem;
@keyframes loaderLine {
75% {
opacity: 1;
}
100% {
opacity: 0;
stroke-dashoffset: 0;
}
}
}
/* --- languages list --- */
.languages-list {
display: flex;
flex-wrap: wrap;
gap: 2.5em;
align-items: center;
padding: 0;
margin: 0;
font-size: .875rem;
line-height: 1.5;
list-style: none;
}
.languages-list__item {
color: $color-text-secondary;
cursor: default;
&--active {
position: relative;
color: $color-text-primary;
&::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
z-index: -1;
display: block;
width: .125rem;
height: 4rem;
background-color: $color-secondary;
transform: translate(-50%, -50%) rotate(45deg);
}
}
&--cross {
$size: 2rem;
$thickness: .125rem;
position: relative;
width: $size;
height: $size;
&::before,
&::after {
content: "";
position: absolute;
top: ($size - $thickness) / 2;
right: 0;
left: 0;
height: $thickness;
background-color: $color-text-primary;
}
&::before {
transform: rotate(45deg);
}
&::after {
transform: rotate(-45deg);
}
}
}
/* --- leaderboard --- */
.leaderboard {
border-collapse: collapse;
font-variant-numeric: tabular-nums;
tbody tr:not(:first-child) {
border-top: .125rem solid $borderColor;
}
th {
color: $color-text-secondary;
font-weight: $fontWeight-normal;
font-size: 1rem;
line-height: 1.5;
text-align: left;
&:nth-child(1) {
width: 6rem;
}
&:nth-child(3),
&:nth-child(4) {
width: 15%;
text-align: right;
}
}
td {
padding: .5em 0;
font-weight: $fontWeight-bold;
font-size: 1.5rem;
line-height: 1.5;
font-family: $font-secondary;
&:nth-child(3),
&:nth-child(4) {
text-align: right;
}
}
}
/* --- login --- */
.login {
display: flex;
flex-direction: column;
}
.login__field + .login__field {
margin-top: .5rem;
}
.login__button {
align-self: center;
margin-top: 2.5rem;
}
/* ------ end: BOARD SCREEN ------ */
/* ------ COUNTDOWN SCREEN ------ */
$countdown-fontSize: 6rem;
$countdown-seconds: 5;
$countdown-elements: $countdown-seconds + 1;
$countdown-fadeHeight: $countdown-fontSize * .5;
$countdown-translateZ: $countdown-fontSize * 1.25;
$countdown-rotateAngle: (360 - (360 / $countdown-elements)) / $countdown-elements;
$countdown-animationDelay: 1s;
$countdown-keyframe: 100% / $countdown-elements;
.countdown {
display: grid;
place-items: center;
animation: screenSlideDown $screenAnimationDuration;
}
.countdown__container {
$size: 36rem;
position: relative;
display: grid;
place-items: center;
width: 100%;
max-width: $size;
height: 100%;
max-height: $size;
}
.countdown__indicator {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.countdown__circle {
$strokeWidth: .125rem;
cx: 50%;
cy: 50%;
r: calc(50% - #{$strokeWidth / 2});
fill: none;
stroke: rgb(255 255 255 / 12%);
stroke-width: $strokeWidth;
}
.countdown__indicator-loader {
$strokeDash: 2000;
stroke: $color-primary;
stroke-dasharray: $strokeDash;
stroke-dashoffset: $strokeDash;
transform: rotate(-90deg);
transform-origin: 50%;
animation: #{$countdown-elements}s countdownIndicator linear forwards;
@keyframes countdownIndicator {
to {
stroke-dashoffset: 0;
}
}
}
/* --- timer --- */
.countdown-timer {
overflow: hidden;
&::before,
&::after {
content: "";
position: relative;
display: block;
z-index: 1;
height: $countdown-fadeHeight;
}
&::before {
background: linear-gradient(to top, rgba($bg, 0), $bg);
}
&::after {
background: linear-gradient(to bottom, rgba($bg, 0), $bg);
}
}
.countdown-timer__rotator {
position: relative;
width: 2ch;
height: $countdown-fontSize;
color: white;
font-size: $countdown-fontSize;
line-height: 1;
text-align: center;
transform-style: preserve-3d;
animation: #{$countdown-elements}s timerRotator forwards;
@keyframes timerRotator {
$step: $countdown-keyframe;
$rotateX: 0deg;
@for $i from 1 through $countdown-elements {
#{$step} {
transform: translateZ(-$countdown-translateZ) rotateX($rotateX);
}
$step: $step + $countdown-keyframe;
$rotateX: $rotateX + $countdown-rotateAngle;
}
}
}
.countdown-timer__item {
position: absolute;
width: 100%;
color: white;
backface-visibility: hidden;
$rotateX: 0deg;
@for $i from 1 through $countdown-elements {
&:nth-child(#{$i}) {
transform: rotateX(-$rotateX) translateZ($countdown-translateZ);
}
$rotateX: $rotateX + $countdown-rotateAngle;
}
}
/* ------ end: COUNTDOWN SCREEN ------ */
/* ------ CHALLENGE SCREEN ------ */
.challenge {
display: grid;
grid-template-areas:
"header header"
"editor info";
grid-template-rows: auto minmax(0, 1fr);
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
gap: 1rem;
padding: $layoutPadding;
animation: screenFadeIn $screenAnimationDuration;
@media (min-width: $breakpoint) {
padding: $layoutPadding-large;
gap: 3.5rem;
}
}
.challenge__header {
grid-area: header;
}
.challenge__editor {
grid-area: editor;
padding: 1em;
margin: 0;
border-radius: .5rem;
overflow: auto;
font-size: 1rem;
line-height: 1.5;
background: #0f0f0f;
&:focus-within {
outline: none;
}
}
.challenge__info {
grid-area: info;
}
/* --- header --- */
.challenge-header {
display: flex;
align-items: center;
column-gap: 3.5rem;
}
.challenge-header__logo {
flex-shrink: 0;
}
.challenge-header__languages-list {
display: none;
@media (min-width: $breakpoint) {
display: flex;
}
}
.challenge-header__timer {
margin-left: auto;
font-variant-numeric: tabular-nums;
}
/* --- tabs --- */
.tabs {
display: flex;
flex-wrap: wrap;
gap: .5rem 1.5rem;
}
.tabs__button {
padding: .5em 0;
margin: 0;
border: none;
border-bottom: .063em solid transparent;
color: $color-text-secondary;
font-size: 1rem;
line-height: 1.5;
font-family: inherit;
background: none;
cursor: pointer;
&--active {
border-color: currentColor;
color: $color-primary;
}
}
/* tabs content */
.tabs-content {
position: relative;
&::before,
&::after {
content: "";
position: absolute;
left: 0;
z-index: 1;
width: 100%;
height: 1.5rem;
}
&::before {
top: 0;
background-image: linear-gradient(to top, rgba(0, 0, 0, 0), $bg);
}
&::after {
bottom: 0;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), $bg);
}
}
.tabs-content__wrapper {
height: 100%;
padding: 3rem 0 1.5rem;
overflow-y: auto;
}
.tabs-content__item {
display: none;
&--active {
display: block;
animation: tabContent .3s; // TODO
@keyframes tabContent {
from {
opacity: 0;
transform: translateX(.5rem);
}
to {
opacity: 1;
transform: translateX(0);
}
}
}
&--results {
h2 {
color: $color-secondary;
}
}
h2 {
margin: 0;
font-weight: $fontWeight-bold;
font-size: 1rem;
line-height: 1.5;
}
p:not(:first-child) {
margin: .75em 0 0;
line-height: 1.5;
}
pre {
margin: 1.5rem 0 0;
font-size: 1rem;
line-height: 1.5;
white-space: pre-wrap;
}
code {
padding: 0 .25em;
border-radius: .25em;
font-size: inherit;
font-family: $font-primary;
background-color: rgb(255 255 255 / 16%);
}
}
/* --- challenge info --- */
.challenge-info {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
}
/* ------ end: CHALLENGE SCREEN ------ */
/* ------ FINISH SCREEN------ */
.finish {
display: grid;
grid-template-rows: auto 1fr;
row-gap: 3rem;
place-items: center;
padding: $layoutPadding;
animation: screenSlideDown $screenAnimationDuration;
@media (min-width: $breakpoint) {
padding: $layoutPadding-large;
}
&--victory {
background-image: radial-gradient(circle 50vw at 50% 0, $bg-victory, rgb(0 0 0 / 0));
}
&--defeat {
background-image: radial-gradient(circle 50vw at 50% 0, $bg-defeat, rgb(0 0 0 / 0));
}
}
.finish__logo {
justify-self: center;
}
.finish__content {
text-align: center;
}
.finish-content__heading {
margin: 0;
font-size: 1.5rem;
line-height: 1.5;
font-family: $font-secondary;
}
.finish-content__text {
margin: 1em 0 0;
line-height: 1.5;
}
.finish-content__button {
margin-top: 2rem;
}
/* ------ end: FINISH SCREEN------ */
// intro
const intro = document.querySelector('.intro');
// board
const board = document.querySelector('.board');
const boardStartButton = board.querySelector('#boardStartButton');
const boardStartLoginButton = board.querySelector('#boardStartLoginButton');
const boardBackButton = board.querySelector('#boardBackButton');
const boardNicknameInput = board.querySelector('#boardNicknameInput');
// countdown
const countdown = document.querySelector('.countdown');
const countdownTimerRotator = countdown.querySelector('.countdown-timer__rotator');
// challenge
const challenge = document.querySelector('.challenge');
const challengeCheckButton = challenge.querySelector('#challengeCheckButton');
// finish
const finish = document.querySelector('.finish');
const finishCompleteButton = finish.querySelector('#finishCompleteButton');
setTimeout(() => {
intro.hidden = true;
board.hidden = false;
}, 4000);
boardStartButton.onclick = () => {
board.classList.add('board--login');
setTimeout(() => {
boardNicknameInput.focus();
}, 300);
};
boardBackButton.onclick = () => {
board.classList.remove('board--login');
};
boardStartLoginButton.onclick = () => {
board.classList.remove('board--login');
board.classList.add('board--waiting');
setTimeout(() => {
board.classList.remove('board--waiting');
board.hidden = true;
countdown.hidden = false;
}, 5000);
}
countdownTimerRotator.onanimationend = () => {
countdown.hidden = true;
challenge.hidden = false;
}
challengeCheckButton.onclick = () => {
challenge.hidden = true;
finish.hidden = false;
}
finishCompleteButton.onclick = () => {
finish.hidden = true;
board.hidden = false;
}
// tabs
(() => {
const tabs = document.querySelector('.tabs');
const tabButtons = document.querySelectorAll('.tabs__button');
const content = document.querySelectorAll('.tabs-content__item');
tabs.onclick = (e) => {
const id = e.target.dataset.id;
const element = document.getElementById(id);
if (id) {
tabButtons.forEach(button => {
button.classList.remove('tabs__button--active');
});
e.target.classList.add('tabs__button--active');
content.forEach(item => {
item.classList.remove('tabs-content__item--active');
});
element.classList.add('tabs-content__item--active');
}
}
})();
Also see: Tab Triggers