Compare commits

...

2 Commits

Author SHA1 Message Date
d3b0c13dad got it going 2025-09-09 18:41:49 -05:00
82c7eed868 fmt: better formatting 2025-09-09 15:27:42 -05:00
12 changed files with 987 additions and 5 deletions

1
.gitignore vendored
View File

@@ -12,3 +12,4 @@ result
*.tfstate
*.tfstate.*
terraform.tfvars

20
.terraform.lock.hcl generated
View File

@@ -1,6 +1,26 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/cloudflare/cloudflare" {
version = "2.19.2"
constraints = "~> 2.19.2"
hashes = [
"h1:gcgDf0Ltyopd5j30oCcnjceCyRpJmSBhTTwldOFnJEc=",
"zh:35a4d37c7601b537e156a032730e2987f137017e38c9a1a383f75cfeccb1975e",
"zh:3bdb1544aef7469813a699ba8d322248c96ffa05573c2bb990e1297aa95473d0",
"zh:41a322d3eeeb0dde185ea7a9cafe952c445a683a6a372089f8d003d8d2f4b722",
"zh:447ec6386879ff56cd3a97fc5d20b428451a445f8846a0127f5788de9e213b3c",
"zh:4a1fa7c6c9e28916009fe3c7a9f7f944e8b4e307ab3d97a34d81ba66769160f6",
"zh:5a2cb0e8ddc725c78ba09a817105136f564c7f4fe0173633d82bc3f8005dc15a",
"zh:83c0edc0ddd6ad8e3c140dcecafccad69edd199d2526cc9be10d857316f3859e",
"zh:a5a1917943a9e8486dc3d0eb315bc899944fe67888e38b35999b6a79907ec762",
"zh:a5cfcd8ec0fd3d0c80de8c519ee07b1e899b8f86d5f6f5800bc959190df9eb93",
"zh:be3a37ef3f0991989a4e51e5fe16d9cf71571cb1ecb7a41b31d91c2ae2a3313d",
"zh:ef1155fd12e3528f686b6a59fc732e35265f8d08450bc27baf8ccebbcd4cff0c",
"zh:f3a2293a7ccb14fa16472c7948498d5a19cb5f26e3aeb1b59756c7f9045c277b",
]
}
provider "registry.terraform.io/hashicorp/aws" {
version = "5.100.0"
constraints = "~> 5.92"

View File

@@ -22,4 +22,3 @@ fmt:
set -euxo pipefail
nix fmt
# shouldn't actually be that hard to put into nix fmt but lazyyy
terraform fmt

124
main.tf Normal file
View File

@@ -0,0 +1,124 @@
provider "aws" {
region = var.aws_region
assume_role {
role_arn = "arn:aws:iam::677425296084:role/tuffas-applier"
}
}
provider "cloudflare" {
}
# block with type resource, uses provider's aws_s3_bucket resource type and names it site
resource "aws_s3_bucket" "site" {
# presumably
bucket = var.site_domain
}
# necessary to allow public users to eventually hit the s3 bucket
resource "aws_s3_bucket_public_access_block" "site" {
bucket = aws_s3_bucket.site.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
# name says it all
resource "aws_s3_bucket_website_configuration" "site" {
bucket = aws_s3_bucket.site.id
# Note that this isn't an =, i don't know why
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
# This controls the ownership of the objects inside the bucket upon upload
# If possible, this sets the ownership of objects to the bucket owner
resource "aws_s3_bucket_ownership_controls" "site" {
bucket = aws_s3_bucket.site.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_acl" "site" {
bucket = aws_s3_bucket.site.id
acl = "public-read"
depends_on = [
aws_s3_bucket_ownership_controls.site,
aws_s3_bucket_public_access_block.site
]
}
# Full permissions for the bucket, which allows anyone to access any object in the bucket
resource "aws_s3_bucket_policy" "site" {
bucket = aws_s3_bucket.site.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "PublicReadGetObject"
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = [
aws_s3_bucket.site.arn,
"${aws_s3_bucket.site.arn}/*",
]
},
]
})
depends_on = [
aws_s3_bucket_public_access_block.site
]
}
# Cloudflare time
# data block is about retrieving data from ext. source, not configuring a resource that lives in state
data "cloudflare_zones" "domain" {
# why a filter?
filter {
name = var.site_domain
}
}
# DNS setup
resource "cloudflare_record" "site_cname" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = var.site_domain
value = aws_s3_bucket_website_configuration.site.website_endpoint
type = "CNAME"
ttl = 1
proxied = true
}
resource "cloudflare_record" "www" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = "www"
value = var.site_domain
type = "CNAME"
ttl = 1
proxied = true
}
resource "cloudflare_page_rule" "https" {
zone_id = data.cloudflare_zones.domain.zones[0].id
target = "*.${var.site_domain}/*"
actions {
always_use_https = true
}
}

14
outputs.tf Normal file
View File

@@ -0,0 +1,14 @@
output "website_bucket_name" {
description = "Name (id) of the bucket"
value = aws_s3_bucket.site.id
}
output "bucket_endpoint" {
description = "Bucket endpoint"
value = aws_s3_bucket_website_configuration.site.website_endpoint
}
output "domain_name" {
description = "Website endpoint"
value = var.site_domain
}

View File

@@ -4,14 +4,18 @@ terraform {
source = "hashicorp/aws"
version = "~> 5.92"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 2.19.2"
}
}
backend "s3" {
region = "us-east-2"
bucket = "hrudayme-test-tfstate"
key = "tuffas-tf"
region = "us-east-2"
bucket = "hrudayme-test-tfstate"
key = "tuffas-tf"
use_lockfile = true
assume_role = { role_arn = "arn:aws:iam::677425296084:role/tfstate_backend_role" }
assume_role = { role_arn = "arn:aws:iam::677425296084:role/tfstate_backend_role" }
}
required_version = ">= 1.2"

View File

@@ -17,5 +17,6 @@
programs.shfmt.enable = true;
programs.yamlfmt.enable = true;
programs.just.enable = true;
programs.terraform.enable = true;
}

9
variables.tf Normal file
View File

@@ -0,0 +1,9 @@
variable "aws_region" {
type = string
description = "The AWS region of this site"
}
variable "site_domain" {
type = string
description = "The domain name of the site"
}

3
website/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Custom Start page
Based on https://github.com/jeroenpardon/sui

View File

@@ -0,0 +1,558 @@
html{
box-sizing: border-box;
moz-box-sizing: border-box;
webkit-box-sizing: border-box;
webkit-text-size-adjust: none;
}
html,
body{
background-color: var(--color-background);
color: var(--color-text-pri);
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif;
font-size: 14px;
font-weight: 400;
height: auto;
letter-spacing: -.012em;
margin: 0;
padding: 0;
webkit-font-smoothing: antialiased;
width: 100vw;
}
*,
*:before,
*:after{
box-sizing: inherit;
moz-box-sizing: inherit;
webkit-box-sizing: inherit;
}
:root{
module-spacing: 3vh;
}
/* TEXT STYLES */
h1, h2{
font-weight: 300;
margin: 0;
padding: 0;
text-align: left;
}
h2, h3, h4{
text-transform: uppercase;
}
h1{
font-size: 4em;
font-weight: 700;
margin-bottom: 0.5em;
}
h2{
font-size: 16px;
height: 30px;
}
h3{
font-size: 20px;
font-weight: 900;
height: 10px;
}
h4{
font-size: 1.1em;
font-weight: 400;
height: 10px;
}
a{
color: var(--color-text-pri);
text-decoration: none;
}
a:hover{
text-decoration: underline;
webkit-text-decoration-color: var(--color-text-acc);
webkit-text-decoration-skip: true;
}
.icon{
font-size: 2.5em;
}
/* FORMS */
input{
background-color: transparent;
border: 0;
border-bottom: thin solid var(--color-text-acc);
color: var(--color-text-pri);
font-size: 0.8em;
height: 3.5em;
transition: all 0.4s ease;
width: 100%;
}
input:focus{
color-border: var(--color-text-pri);
outline: none;
}
input:focus{
opacity: 1;
}
/* TABLES */
table{
border: thin solid #e4e4e4;
border-collapse: collapse;
border-spacing: 0;
font-size: 1em;
text-align: left;
width: 100%;
}
table td:nth-of-type(2){
padding-right: 5em;
}
table td{
border: thin solid #e4e4e4;
color: #333333;
font-size: 1em;
overflow: hidden;
padding: 10px 5px;
word-break: normal;
}
table th{
border: thin solid #e4e4e4;
color: #333333;
font-weight: bold;
padding: 10px 5px;
}
table a{
color: #333333;
}
/* ANIMATION */
.fade{
opacity: 0;
}
@keyframes fadeseq{
100% {
opacity: 1;
}
}
.fade{
opacity: 0;
}
.fade{
animation: fadeseq .3s forwards;
}
.fade:nth-child(2){
animation-delay: .4s;
}
/* LAYOUT */
#container{
align-items: stretch;
display: grid;
grid-column-gap: 20px;
grid-row-gap: 3vh;
grid-template-columns: 1fr;
grid-template-rows: 12vh 4vh auto;
justify-items: stretch;
margin-left: auto;
margin-right: auto;
margin-top: 5vh;
width: 60%;
}
/* SECTIONS */
#header{
border-bottom: 0px solid var(--color-text-acc);
z-index: 1;
}
#apps_loop{
border-bottom: 0px solid var(--color-text-acc);
display: grid;
grid-column-gap: 0px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 64px;
padding-bottom: var(--module-spacing);
}
.apps_icon{
height: 64px;
margin-right: 1em;
padding-top: 15px;
}
.apps_icon span{
font-size: 2.5em;
line-height: 3rem;
}
.apps_item{
display: flex;
flex-direction: row;
flex-wrap: wrap;
height: 64px;
margin: 0;
}
.apps_text{
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
overflow: hidden;
}
.apps_text a{
font-size: 1em;
font-weight: 500;
text-transform: uppercase;
}
.apps_text span{
color: var(--color-text-acc);
font-size: 0.8em;
text-transform: uppercase;
}
#links_loop{
display: grid;
flex-wrap: nowrap;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto;
}
#links_item{
line-height: 1.5rem;
margin-bottom: 2em;
webkit-font-smoothing: antialiased;
}
#links_item h4{
color: var(--color-text-acc);
}
#links_item a{
display: block;
line-height: 2;
}
/* MODAL */
#modal{
overflow-y: auto;
bottom: 0;
left: 0;
opacity: 0;
pointer-events: none;
position: fixed;
right: 0;
top: 0;
transition: all 0.3s;
z-index: 20;
}
#modal:target{
opacity: 1;
pointer-events: auto;
}
#modal>div{
background-color: #ffffff;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.30), 0 15px 12px rgba(0, 0, 0, 0.25);
margin-left: auto;
margin-right: auto;
padding: 2em;
margin-top: 5vh;
width: 50%;
display: flex;
flex-direction: column;
}
#modal h1{
color: #333333;
font-size: 2em;
}
#modal h2{
margin-top:1.5em;
}
#modal-header{
display:flex;
justify-content: space-between;
}
#modal-footer{
display:flex;
font-size:2em;
justify-content: flex-start;
}
#modal-footer a{
margin-right:0.25em;
}
.modal-close{
color: #000000;
font-size: 1.5em;
text-align: center;
text-decoration: none;
}
.modal-close:hover{
color: #000;
}
#modal_init a{
bottom: 1vh;
color: var(--color-text-acc);
left: 1vw;
position: fixed;
}
#modal_init a:hover{
color: var(--color-text-pri);
}
#modal-theme{
border-bottom: 0px solid var(--color-text-acc);
display: flex;
flex-wrap: wrap;
margin-bottom: 2em;
}
#providers{
margin-bottom: 2em;
}
/* THEMING */
.theme-button{
font-size: 0.8em;
margin: 2px;
width:128px;
line-height: 3em;
text-align: center;
text-transform: uppercase;
}
.theme-blackboard{
background-color: #000000;
border: 4px solid #5c5c5c;
color: #FFFDEA;
}
.theme-gazette{
background-color: #F2F7FF;
border: 4px solid #5c5c5c;
color: #000000;
}
.theme-espresso{
background-color: #21211F;
border: 4px solid #4E4E4E;
color: #D1B59A;
}
.theme-cab{
background-color: #FEED01;
border: 4px solid #424242;
color: #1F1F1F;
}
.theme-cloud{
background-color: #f1f2f0;
border: 4px solid #35342f;
color: #37bbe4;
}
.theme-lime{
background-color: #263238;
border: 4px solid #AABBC3;
color: #aeea00;
}
.theme-passion{
background-color: #f5f5f5;
border: 4px solid #8e24aa;
color: #12005e;
}
.theme-blues{
background-color: #2B2C56;
border: 4px solid #6677EB;
color: #EFF1FC;
}
.theme-chalk{
background-color: #263238;
border: 4px solid #FF869A;
color: #AABBC3;
}
.theme-tron{
background-color: #242B33;
border: 4px solid #6EE2FF;
color: #EFFBFF;
}
.theme-paper{
background-color: #F8F6F1;
border: 4px solid #F5E1A4;
color: #4C432E;
}
/* MEDIA QUERIES */
@media screen and (max-width: 1260px)
{
#container
{
align-items: stretch;
display: grid;
grid-column-gap: 10px;
grid-row-gap: 0px;
grid-template-columns: 1fr;
grid-template-rows: 80px auto;
justify-items: stretch;
margin-bottom: 1vh;
margin-left: auto;
margin-right: auto;
width: 90%;
}
#apps_loop{
grid-template-columns: 1fr 1fr 1fr;
width: 100vw;
}
#links_loop {
grid-template-columns: 1fr 1fr 1fr;
}
#modal>div{
margin-left: auto;
margin-right: auto;
margin-top: 5vh;
width: 90%;
}
}
@media screen and (max-width: 667px)
{
html{
font-size: calc(16px + 6 * ((100vw - 320px) / 680));
}
#container{
align-items: stretch;
display: grid;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr;
grid-template-rows: 80px auto;
justify-items: stretch;
margin-bottom: 1vh;
width: 90%;
}
h1{
font-size: 4em;
height: auto;
margin-bottom: 0em;
}
h2{
font-size: 1em;
height: auto;
margin-bottom: 0em;
}
h3{
font-size: 1em;
}
#apps_loop{
grid-column-gap: 0px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr;
width: 100vw;
}
.apps_icon{
height: 64px;
margin-right: 0.8em;
padding-top: 14px;
}
.apps_icon span{
font-size: 2em;
line-height: 2.5rem;
}
#links_loop{
display: grid;
flex-wrap: nowrap;
grid-column-gap: 20px;
grid-row-gap: 0px;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
}
}
/* Small Screens */
@media only screen and (max-width: 400px) {
#app-address {
display: none;
}
}

220
website/assets/js/script.js Normal file
View File

@@ -0,0 +1,220 @@
function date() {
let currentDate = new Date();
let dateOptions = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
};
let date = currentDate.toLocaleDateString("en-GB", dateOptions);
document.getElementById("header_date").innerHTML = date;
}
function greet() {
let currentTime = new Date();
let greet = Math.floor(currentTime.getHours() / 6);
switch (greet) {
case 0:
document.getElementById("header_greet").innerHTML = "Good night!";
break;
case 1:
document.getElementById("header_greet").innerHTML = "Good morning!";
break;
case 2:
document.getElementById("header_greet").innerHTML = "Good afternoon!";
break;
case 3:
document.getElementById("header_greet").innerHTML = "Good evening!";
break;
}
}
const strategies = [
"(Organic) machinery",
"A line has two sides",
"A very small object Its center",
"Abandon desire",
"Abandon normal instructions",
"Abandon normal instruments",
"Accept advice",
"Accretion",
"Adding on",
"Allow an easement (an easement is the abandonment of a stricture)",
"Always first steps",
"Always give yourself credit for having more than personality",
"Are there sections? Consider transitions",
"Ask people to work against their better judgement",
"Ask your body",
"Assemble some of the elements in a group and treat the group",
"Balance the consistency principle with the inconsistency principle",
"Be dirty",
"Be extravagant",
"Be less critical",
"Breathe more deeply",
"Bridges -build -burn",
"Cascades",
"Change ambiguities to specifics",
"Change instrument roles",
"Change nothing and continue with immaculate consistency",
"Change specifics to ambiguities",
"Children -speaking -singing",
"Cluster analysis",
"Consider different fading systems",
"Consider transitions",
"Consult other sources -promising -unpromising",
"Convert a melodic element into a rhythmic element",
"Courage!",
"Cut a vital connection",
"Decorate, decorate",
"Define an area as 'safe' and use it as an anchor",
"Destroy -nothing -the most important thing",
"Discard an axiom",
"Disciplined self-indulgence",
"Disconnect from desire",
"Discover the recipes you are using and abandon them",
"Display your talent",
"Distorting time",
"Do nothing for as long as possible",
"Do something boring",
"Do something sudden, destructive and unpredictable",
"Do the last thing first",
"Do the washing up",
"Do the words need changing?",
"Do we need holes?",
"Don't avoid what is easy",
"Don't be frightened of cliches",
"Don't break the silence",
"Don't stress one thing more than another",
"Don't be afraid of things because they're easy to do",
"Don't be frightened to display your talents",
"Emphasize differences",
"Emphasize repetitions",
"Emphasize the flaws",
"Faced with a choice, do both",
"Feed the recording back out of the medium",
"Fill every beat with something",
"Find a safe part and use it as an anchor",
"Get your neck massaged",
"Ghost echoes",
"Give the game away",
"Give the name away",
"Give way to your worst impulse",
"Go outside. Shut the door.",
"Go slowly all the way round the outside",
"Go to an extreme, come part way back",
"Honor thy error as a hidden intention",
"How would someone else do it?",
"How would you have done it?",
"Humanize something free of error",
"Idiot glee (?)",
"Imagine the piece as a set of disconnected events",
"In total darkness, or in a very large room, very quietly",
"Infinitesimal gradations",
"Intentions -nobility of -humility of -credibility of",
"Into the impossible",
"Is it finished?",
"Is something missing?",
"Is the information correct?",
"Is the style right?",
"It is quite possible (after all)",
"It is simply a matter of work",
"Just carry on",
"Left channel, right channel, center channel",
"Listen to the quiet voice",
"Look at the order in which you do things",
"Look closely at the most embarrassing details & amplify them",
"Lost in useless territory",
"Lowest common denominator",
"Magnify the most difficult details",
"Make a blank valuable by putting it in an exquisite frame",
"Make a sudden, destructive unpredictable action; incorporate",
"Make an exhaustive list of everything you might do \n& do the last thing on the list",
"Make it more sensual",
"Make what's perfect more human",
"Mechanicalize something idiosyncratic",
"Move towards the unimportant",
"Mute and continue",
"Not building a wall but making a brick",
"Once the search has begun, something will be found",
"Only a part, not the whole",
"Only one element of each kind",
"Overtly resist change",
"Put in earplugs",
"Question the heroic approach",
"Reevaluation (a warm feeling)",
"Remember those quiet evenings",
"Remove a restriction",
"Remove ambiguities and convert to specifics",
"Remove specifics and convert to ambiguities",
"Repetition is a form of change",
"Retrace your steps",
"Reverse",
"Short circuit \n(example: a man eating peas with the idea that they will improve his virility \nshovels them straight into his lap)",
"Simple subtraction",
"Simply a matter of work",
"Slow preparation, fast execution",
"Spectrum analysis",
"State the problem in words as clearly as possible",
"Take a break",
"Take away the elements in order of apparent non-importance",
"Take away the important parts",
"Tape your mouth",
"The inconsistency principle",
"The most important thing is the thing most easily forgotten",
"The tape is now the music",
"Think - inside the work -outside the work",
"Think of the radio",
"Tidy up",
"Towards the insignificant",
"Trust in the you of now",
"Try faking it",
"Turn it upside down",
"Twist the spine",
"Use 'unqualified' people",
"Use an old idea",
"Use an unacceptable color",
"Use cliches",
"Use fewer notes",
"Use filters",
"Use something nearby as a model",
"Use your own ideas",
"Voice your suspicions",
"Water",
"What are the sections sections of? Imagine a caterpillar moving",
"What are you really thinking about just now?",
"What context would look right?",
"What is the reality of the situation?",
"What is the simplest solution?",
"What mistakes did you make last time?",
"What to increase? What to reduce? What to maintain?",
"What would your closest friend do?",
"What wouldn't you do?",
"When is it for?",
"Where is the edge?",
"Which parts can be grouped?",
"Work at a different speed",
"Would anyone want it?",
"You are an engineer",
"You can only make one dot at a time",
"You don't have to be ashamed of using your own ideas",
"[blank white card]"
];
const pickStrategy = () => {
let strategyNumber = Math.floor(Math.random() * strategies.length);
return strategies[strategyNumber];
};
const strategize = () => {
let strat = pickStrategy();
document.getElementById("header_strategy").innerHTML = strat;
}
function loadFunctions() {
date();
greet();
strategize();
}

29
website/index.html Normal file
View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>deepak.science</title>
<meta charset="utf-8">
<meta http-equiv="Default-Style" content="">
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
<link type="text/css" rel="stylesheet" href="./assets/css/styles.css" media="screen,projection"/>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900" rel="stylesheet">
</head>
<body onload="loadFunctions()">
<main id="container" class="fade">
<section id="header">
<h2 id="header_date"></h2>
<h1 id="header_greet"></h1>
</section>
<section id="strategies">
<h2 id="header_strategy"></h2>
</section>
</main>
<script src="./assets/js/script.js" type="text/javascript"></script>
</body>
</html>