diff --git a/.gitignore b/.gitignore index 62e4390..cb78655 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ assets/js/dist # Script cleanup +startup *Zone.Identifier \ No newline at end of file diff --git a/_includes/test.html b/_includes/test.html deleted file mode 100644 index 4437198..0000000 --- a/_includes/test.html +++ /dev/null @@ -1,3 +0,0 @@ -

- hello -

\ No newline at end of file diff --git a/_layouts/projects.html b/_layouts/projects.html new file mode 100644 index 0000000..81afc98 --- /dev/null +++ b/_layouts/projects.html @@ -0,0 +1,21 @@ +--- +layout: default +refactor: true +--- + +{% include lang.html %} + +
+ {% if page.layout == 'page' or page.collection == 'tabs' %} + {% assign tab_key = page.title | downcase %} + {% assign title = site.data.locales[lang].tabs[tab_key] | default: page.title %} +

+ {{ title }} +

+
+ {{ content }} +
+ {% else %} + {{ content }} + {% endif %} +
\ No newline at end of file diff --git a/_posts/2024-03-24-unbreakable-individual-2024 copy.md b/_posts/2024-03-24-unbreakable-individual-2024.md similarity index 99% rename from _posts/2024-03-24-unbreakable-individual-2024 copy.md rename to _posts/2024-03-24-unbreakable-individual-2024.md index 8de0b90..bc084f9 100644 --- a/_posts/2024-03-24-unbreakable-individual-2024 copy.md +++ b/_posts/2024-03-24-unbreakable-individual-2024.md @@ -2,7 +2,7 @@ title: Unbreakable Individual 2024 date: 2024-03-24 12:00:00 -500 categories: [CTF Writeups, Unbreakable] -tags: [reverse,mobile,web,forsenics,steganography,osint,crypto] +tags: [reverse,mobile,web,forsenics,stegano,osint,crypto] image: /assets/img/logos/logo-unbreakable.png --- diff --git a/_posts/2024-09-10-cyberedu-bork-sauls.md b/_posts/2024-09-10-cyberedu-bork-sauls.md new file mode 100644 index 0000000..c1c58f0 --- /dev/null +++ b/_posts/2024-09-10-cyberedu-bork-sauls.md @@ -0,0 +1,89 @@ +--- +title: Bork Sauls - CyberEDU +date: 2024-09-10 07:00:00 -500 +categories: [CTF Writeups, CyberEdu, Reverse] +tags: [reverse,integer-overflow] +image: /assets/img/logos/cyberedu.png + +--- +# Bork Sauls - CyberEDU + +**Flag : ctf{d8194ce78a6c555adae9c14fe56674e97ba1afd88609c99dcb95fc599dcbc9f5}** +- Difficulty: Easy + +Firstly, I decompiled the file to see what is inside. + +![image](https://github.com/Inf3n0s/CTF-Writeups/assets/75357316/47bce577-0bdc-4369-93c0-2247be6d0ce3) + +```c +undefined8 main(EVP_PKEY_CTX *param_1) +{ + int local_14; + int local_10; + uint local_c; + + init(param_1); + local_c = 100000; + local_10 = 0; + puts("You enter the room, and you meet the Dancer of the Boreal Valley. You have 3 options."); + do { + puts("Choose: \n1.Roll\n2.Hit(only 3 times)\n3.Throw Estus flask at the boss (wut?)\n4.Alt-F4\n" + ); + __isoc99_scanf(&DAT_001020b5,&local_14); + if (local_14 == 3) { + local_c = local_c + 1999999; + } + else if (local_14 < 4) { + if (0 < local_14) { + if (local_10 < 3) { + local_c = local_c - 30000; + } + local_10 = local_10 + 1; + } + } + else if (local_14 == 4) { + /* WARNING: Subroutine does not return */ + exit(0); + } + printf("Health: %d\n",(ulong)local_c); + } while (-1 < (int)local_c); + printf("Congratulations. Here\'s your flag: "); + system("cat flag.txt"); + return 0; +} +``` + +I understand what I need to do : +```c +if(-1 > (int)local_c); +``` + +I will go on pass to the instruction where `cat flag` + +OK, but in normal mode you think it's impossible. Hmm, INT_MAX = **2147483647**, but what happened if you increment the "INT_MAX" => INT_MIN = -INT_MAX = **-2147483647** which is negative => GG + +## Solve script: +```python +from pwn import * + + +context.log_level = "debug" + +r = remote("34.159.73.134", 30149) +#r = process("./bork_sauls") + +INT_MAX = 2147483647 # maximum value of an int (C/C++) + +health = 100000 +health_added = 1999999 + +while health < INT_MAX: + health += health_added + r.recvuntil(b"4.Alt-F4") + r.sendline(b"3") + +r.recvuntil(b"Here's your flag: ") +flag = r.recvline().strip().decode() + +print(flag) +``` diff --git a/_posts/2024-09-10-cyberedu-flag-is-hidden.md b/_posts/2024-09-10-cyberedu-flag-is-hidden.md new file mode 100644 index 0000000..1ab19e8 --- /dev/null +++ b/_posts/2024-09-10-cyberedu-flag-is-hidden.md @@ -0,0 +1,27 @@ +--- +title: Flag is hidden - CyberEDU +date: 2024-09-10 07:00:00 -500 +categories: [CTF Writeups, CyberEdu, Mobile] +tags: [reverse,mobule,apktool,stegano] +image: /assets/img/logos/cyberedu.png + +--- +# Flag is hidden - CyberEDU + +**Flag : ECSC{a3cfc7f4f812cc4b511f6de4dc150422f49e817c0f61321852a81e6b5f3961ba}** +- Difficulty: **Easy** + +For this challenge I use 2 tools: `JADX-GUI` and `APKtool` + +Firstly I like to look in `JADX-GUI` to check code and resources. + +![image](https://github.com/Inf3n0s/CTF-Writeups/assets/75357316/2099bc80-2a66-4deb-a010-e037f39b8e16) + +Good in challenge description, we found a hint `PS: stegano tools can "rock your" score` => stegano + "rockyou.txt" + +I use `apktool d flag.apk` and I search the image and I use [`stegcracker`](https://github.com/Paradoxis/StegCracker) to find what is inside +`stegcracker ./flag/res/drawable-v24/splash.jpg /usr/share/wordlists/rockyou.txt` + +After that `cat ./flag/res/drawable-v24/splash.jpg.out` => `fla................................................GGGGGG{RUNTQ3thM2NmYzdmNGY4MTJjYzRiNTExZjZkZTRkYzE1MDQyMmY0OWU4MTdjMGY2MTMyMTg1MmE4MWU2YjVmMzk2MWJhfQ==}` + +![image](https://github.com/Inf3n0s/CTF-Writeups/assets/75357316/2d44a7ea-1987-4a1b-bfdb-0819c6d11e05) diff --git a/_posts/2024-09-10-cyberedu-old-school.md b/_posts/2024-09-10-cyberedu-old-school.md new file mode 100644 index 0000000..6b0ec76 --- /dev/null +++ b/_posts/2024-09-10-cyberedu-old-school.md @@ -0,0 +1,184 @@ +--- +title: Old School - ROCSC && CyberEDU +date: 2024-09-10 07:00:00 -500 +categories: [CTF Writeups, CyberEdu, ROCSC, Reverse] +tags: [reverse,cracking] +image: /assets/img/logos/cyberedu.png + +--- +# Old School - ROCSC && CyberEDU + +**Flag : ROSCSC{LCRO-ECSC-8989-1918}** +- Difficulty: **Medium** + +Firstly, check out the description because, this challenge it's so tricky : `formatul ROSCSC{cod_licenta}.` REMEMBER **`ROSCSC`** it's the first part of the flag, for example I lose 20 minutes to find what is wrong with my flag. + +Let's dive in: +```python +└──╼ $strings Uncrackable.exe +!This program cannot be run in DOS mode. +Rich +.text +`.data +.rsrc +MSVBVM60.DLL +Uncrackable +Form1 +Uncrackable license checker +Form1 +Command1 +Verificare +Text1 +Label1 +License code: +VB5! +Uncrackable +Uncrackable +Uncrackable +Form1 +Uncrackable +Label1 +C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.OLB +``` + +Now I find the program it's a Visual Basics (VB) App. Now, I search [VB Decompiler](https://www.vb-decompiler.org/download.htm) and that's I found, I test on my self, but if you don't want to run "untrusted" softwares, I will attach the decomplied version in writeup. + +```cs +Data Table: 40288C + loc_402BD8: LitStr "LCRO" + loc_402BDB: FStStrCopy var_8C + loc_402BDE: LitStr "CSCE" + loc_402BE1: ImpAdCallI2 StrReverse() + loc_402BE6: FStStr var_90 + loc_402BE9: LitI2 8989 + loc_402BEC: FStI2 var_92 + loc_402BEF: LitI2_Byte 1 + loc_402BF1: CUI1I2 + loc_402BF3: LitI4 1 + loc_402BF8: FLdRfVar var_AC + loc_402BFB: Ary1StUI1 + loc_402BFD: LitI2_Byte 9 + loc_402BFF: CUI1I2 + loc_402C01: LitI4 2 + loc_402C06: FLdRfVar var_AC + loc_402C09: Ary1StUI1 + loc_402C0B: LitI2_Byte 1 + loc_402C0D: CUI1I2 + loc_402C0F: LitI4 3 + loc_402C14: FLdRfVar var_AC + loc_402C17: Ary1StUI1 + loc_402C19: LitI2_Byte 8 + loc_402C1B: CUI1I2 + loc_402C1D: LitI4 4 + loc_402C22: FLdRfVar var_AC + loc_402C25: Ary1StUI1 + loc_402C27: LitStr "-" + loc_402C2A: FStStrCopy var_B4 + loc_402C2D: ILdRf var_8C + loc_402C30: ILdRf var_B4 + loc_402C33: ConcatStr + loc_402C34: FStStrNoPop var_BC + loc_402C37: ILdRf var_90 + loc_402C3A: ConcatStr + loc_402C3B: FStStrNoPop var_C0 + loc_402C3E: ILdRf var_B4 + loc_402C41: ConcatStr + loc_402C42: FStStrNoPop var_C4 + loc_402C45: FLdI2 var_92 + loc_402C48: CStrUI1 + loc_402C4A: FStStrNoPop var_C8 + loc_402C4D: ConcatStr + loc_402C4E: FStStrNoPop var_CC + loc_402C51: ILdRf var_B4 + loc_402C54: ConcatStr + loc_402C55: FStStrNoPop var_D0 + loc_402C58: LitI4 1 + loc_402C5D: FLdRfVar var_AC + loc_402C60: Ary1LdUI1 + loc_402C62: CStrI2 + loc_402C64: FStStrNoPop var_D4 + loc_402C67: ConcatStr + loc_402C68: FStStrNoPop var_D8 + loc_402C6B: LitI4 2 + loc_402C70: FLdRfVar var_AC + loc_402C73: Ary1LdUI1 + loc_402C75: CStrI2 + loc_402C77: FStStrNoPop var_DC + loc_402C7A: ConcatStr + loc_402C7B: FStStrNoPop var_E0 + loc_402C7E: LitI4 3 + loc_402C83: FLdRfVar var_AC + loc_402C86: Ary1LdUI1 + loc_402C88: CStrI2 + loc_402C8A: FStStrNoPop var_E4 + loc_402C8D: ConcatStr + loc_402C8E: FStStrNoPop var_E8 + loc_402C91: LitI4 4 + loc_402C96: FLdRfVar var_AC + loc_402C99: Ary1LdUI1 + loc_402C9B: CStrI2 + loc_402C9D: FStStrNoPop var_EC + loc_402CA0: ConcatStr + loc_402CA1: FStStr var_B8 + loc_402CA4: FFreeStr var_BC = "": var_C0 = "": var_C4 = "": var_C8 = "": var_CC = "": var_D0 = "": var_D4 = "": var_D8 = "": var_DC = "": var_E0 = "": var_E4 = "": var_E8 = "" + loc_402CC1: FLdRfVar var_BC + loc_402CC4: FLdPrThis + loc_402CC5: VCallAd Control_ID_Text1 + loc_402CC8: FStAdFunc var_F0 + loc_402CCB: FLdPr var_F0 + loc_402CCE: = Me.Text + loc_402CD3: FLdZeroAd var_BC + loc_402CD6: FStStr var_88 + loc_402CD9: FFree1Ad var_F0 + loc_402CDC: ILdRf var_B8 + loc_402CDF: ILdRf var_88 + loc_402CE2: EqStr + loc_402CE4: BranchF loc_402D13 + loc_402CE7: LitVar_Missing var_170 + loc_402CEA: LitVar_Missing var_150 + loc_402CED: LitVar_Missing var_130 + loc_402CF0: LitI4 0 + loc_402CF5: LitVarStr var_100, "Cracked!" + loc_402CFA: FStVarCopyObj var_110 + loc_402CFD: FLdRfVar var_110 + loc_402D00: ImpAdCallFPR4 MsgBox(, , , , ) + loc_402D05: FFreeVar var_110 = "": var_130 = "": var_150 = "" + loc_402D10: Branch loc_402D3C + loc_402D13: LitVar_Missing var_170 + loc_402D16: LitVar_Missing var_150 + loc_402D19: LitVar_Missing var_130 + loc_402D1C: LitI4 0 + loc_402D21: LitVarStr var_100, "Incearca mai tare" + loc_402D26: FStVarCopyObj var_110 + loc_402D29: FLdRfVar var_110 + loc_402D2C: ImpAdCallFPR4 MsgBox(, , , , ) + loc_402D31: FFreeVar var_110 = "": var_130 = "": var_150 = "" + loc_402D3C: ExitProcHresult +``` + +```cs + loc_402CDC: ILdRf var_B8 + loc_402CDF: ILdRf var_88 + loc_402CE2: EqStr +``` +var_88 will be the license code input, which will be compere with var_B8 = correct license code + +```cs +var_8C = "LCRO" +var90 = reverse("CSCE") = "ECSC" +var92 = 8989 +var_AC it's a vector => 1918 +``` + +This instructions add "-" in each part of license code +```cs + loc_402C27: LitStr "-" + loc_402C2A: FStStrCopy var_B4 + loc_402C2D: ILdRf var_8C + loc_402C30: ILdRf var_B4 + loc_402C33: ConcatStr +``` + +=> License code = **LCRO-ECSC-8989-1918** + +And GG, we successful crack the program and found flag. \ No newline at end of file diff --git a/_posts/2024-09-10-hackthebox-lost-modulus.md b/_posts/2024-09-10-hackthebox-lost-modulus.md new file mode 100644 index 0000000..53d2708 --- /dev/null +++ b/_posts/2024-09-10-hackthebox-lost-modulus.md @@ -0,0 +1,68 @@ +--- +title: LostModulus - HackTheBox +date: 2024-09-10 07:00:00 -500 +categories: [CTF Writeups, Hackthebox, Crypto] +tags: [Crypto,RSA,Small e] +image: /assets/img/logos/htb/htb-crypto.png +math: true +--- +# LostModulus - HackTheBox + +**Flag : HTB{n3v3r_us3_sm4ll_3xp0n3n7s_f0r_rs4}** +- Difficulty: **Very Easy** + +The challenge provides a RSA script and the ciphertext. The script is using a **small e** value which is a common mistake in RSA implementation. + +```python +# Challenge.py +#!/usr/bin/python3 +from Crypto.Util.number import getPrime, long_to_bytes, inverse +flag = open('flag.txt', 'r').read().strip().encode() + +class RSA: + def __init__(self): + self.p = getPrime(512) + self.q = getPrime(512) + self.e = 3 + self.n = self.p * self.q + self.d = inverse(self.e, (self.p-1)*(self.q-1)) + def encrypt(self, data: bytes) -> bytes: + pt = int(data.hex(), 16) + ct = pow(pt, self.e, self.n) + return long_to_bytes(ct) + def decrypt(self, data: bytes) -> bytes: + ct = int(data.hex(), 16) + pt = pow(ct, self.d, self.n) + return long_to_bytes(pt) + +def main(): + crypto = RSA() + print ('Flag:', crypto.encrypt(flag).hex()) + +if __name__ == '__main__': + main() +``` + +```plaintext +Flag: 05c61636499a82088bf4388203a93e67bf046f8c49f62857681ec9aaaa40b4772933e0abc83e938c84ff8e67e5ad85bd6eca167585b0cc03eb1333b1b1462d9d7c25f44e53bcb568f0f05219c0147f7dc3cbad45dec2f34f03bcadcbba866dd0c566035c8122d68255ada7d18954ad604965 +``` + +## Source code analysis +The challenge script is using $ e=3 $, which is the exponent used for encryption. In RSA, $m$ is the plain text, $c$ is the ciphertext and $n$ is the modulus : +$$ c = m^e \mod{n} $$ + +## Solution +Since the exponent is small and we don't have n ( we can take a hint from the title *"Lost Modulus"*), we can easily calculate the cube root of the ciphertext to get the plaintext. This can work if the message is short enough to satisfy the condition $m^3 = c < n$, so the modulus doesn't affect the result. + +```python +import gmpy2 +c = int('05c61636499a82088bf4388203a93e67bf046f8c49f62857681ec9aaaa40b4772933e0abc83e938c84ff8e67e5ad85bd6eca167585b0cc03eb1333b1b1462d9d7c25f44e53bcb568f0f05219c0147f7dc3cbad45dec2f34f03bcadcbba866dd0c566035c8122d68255ada7d18954ad604965', 16) +integer = gmpy2.iroot(c, 3)[1] +## Here I test if the cube root is an integer +assert integer == True +m = gmpy2.iroot(c, 3)[0] +flag = bytes.fromhex(hex(m)[2:]).decode() +print(flag) +``` + +And works, we get the flag, voila! 💚 \ No newline at end of file diff --git a/_posts/2024-09-10-hackthebox-spooky-rsa.md b/_posts/2024-09-10-hackthebox-spooky-rsa.md new file mode 100644 index 0000000..ff9a182 --- /dev/null +++ b/_posts/2024-09-10-hackthebox-spooky-rsa.md @@ -0,0 +1,80 @@ +--- +title: Spooky RSA - HackTheBox +date: 2024-09-10 07:00:00 -500 +categories: [CTF Writeups, Hackthebox, Crypto] +tags: [Crypto,RSA,GCD] +image: /assets/img/logos/htb/htb-crypto.png +math: true +--- +# Spooky RSA - HackTheBox + +**Flag : HTB{cu570m_83475_73x7800k_3v32y_71m3}** +- Difficulty: **Easy** + +We got the Python source code used to encrypt the flag: + +```python +from Crypto.Util.number import bytes_to_long, getStrongPrime +from random import randint + +FLAG = b'HTB{????????????????????????????????????????????}' + + +def key_gen(bits): + p, q = getStrongPrime(bits), getStrongPrime(bits) + N = p * q + return N, (p, q) + + +def encrypt(m, N, f): + e1, e2 = randint(2, N - 2), randint(2, N - 2) + c1 = (pow(f, e1, N) + m) % N + c2 = (pow(f, e2, N) + m) % N + return (e1, c1), (e2, c2) + + +def main(): + N, priv = key_gen(1024) + + m = bytes_to_long(FLAG) + + (e1, c1), (e2, c2) = encrypt(m, N, priv[0]) + + with open('out.txt', 'w') as f: + f.write(f'N = {N}\n(e1, c1) = ({e1}, {c1})\n(e2, c2) = ({e2}, {c2})\n') + + +if __name__ == "__main__": + main() +``` +and we also have the output of the encryption: + +```plaintext +N = 23252667157599516940129524769090828719982590926217686828297820221246528288024986185770032891432071416316776607472816043745785945382619303771286924656092974519197669053189283351571920071432553222222811904112119520974410020093306071010335958643236508606549664330684556056421228904824554943559829654154540793885983689462338911148618911233437943092856313175212883771802928968521215461427230178865304889974060408714941809216551397552099050566216607216463931428967751885004128977314044993037370392135272264982092147566078177173327860726953745529225163314733863792635537495622731398807790511518482833382759873192115192207209 +(e1, c1) = (13130317383799359924397818711045172877651070470639872331555061566871077024416132122821689879197166729443692993224787531055068053553245916779683406195947939469930710138275745308571705318328750438377477058341710049450433868075025011970534711610887418427142999431981800104300319735079412330836192720430158369804693687507459455621592955618266507196962663247417904680299143606004651444970274693793668715761929296821908860947834841947073379537992600397854852337772316114987249254395674689638512533430273885970458183044843553777077752747556298072797820716079692849044148071698585069757021266842594074685187380985522959676924, 3276033314700994933236715546269096681595964054694634317877930652961630783669009686295177734678226788913957176667505963284895192875563765999040362544244408645923937742131293085082421535485813399270056524297324864682622089578866968706269063489779845211872503005591066652086230371845356855417702566514946373846876609725394545339840695130518357770158558391396835218039249572390662833461220605497534710914935522013573314984887838699014465554643808438475560847600079478934259045848291858470555503523718530137358192672530066755416937024529536303824075068992110042077005432280129307864841939511235555989308133055235385105960) +(e2, c2) = (20883594128285008437725229014478679601366127938823960100219581029154081635436411892478004501333834114219976189312792835720670788637746570550119467812230092062199251164946197959206350494458367692847308442685450722126282132876286895613925612558140177853699821618151096670620765409968557233259334756429446973833981043722454375455334033442236036896820634662734963958738789068654435207820624411915045062084652483285735900502029367176441696762291709434815865847363600312665970290960775666366786471564595838531305478536744797611070398211876965476639913075928103807981832916853895307250848232566714169131101439494532639396872, 18023359039022070922496207692467909272905633400500071646677663883848372907925575359795644502829612958089930556811098737564701111791300315722656180784065385762079524349557515732188405944474314448560602595952205309214787356604461723684793632495397765839132359663293143446639091410994479947265462557919856471699351934094395015205994443217852376256039110600437586852484006845325143039405449700872936218023776566918818003785468900212143526790175840288515458337112681822830546618062507825380629100313042086810588864941567987823223444256356108148388871548275890051441470007397336976314029406010035567308845594636823378393001) +``` + +## Source code analysis +The script generates a pair of primes $p$ and $q$ and calculates the modulus $N = p \times q$. The flag is encrypted using two random exponents $e_1$ and $e_2$ and the public key $f = p$. The ciphertexts $c_1$ and $c_2$ are calculated as follows: +$$c_1 = (f^{e_1} + m) \mod{N}$$ +$$c_2 = (f^{e_2} + m) \mod{N}$$ + +## Solution +First, we saw that the public key $f$ is equal to $p$. We can calculate the $c_1 - c_2 = p^{e_1} - p^{e_2} = p \cdot (p^{e_1 - 1}- p^{e_2 - 1}) \mod{N}$ + +We can calculate the greatest common divisor (GCD) of $N$ and $c_1 - c_2$ to find the common factor $p$: + +Once we have $p$, we can calculate $m = c_1 - p^{e_1} \mod{N}$ + +### Solve script +```python +N = 23252667157599516940129524769090828719982590926217686828297820221246528288024986185770032891432071416316776607472816043745785945382619303771286924656092974519197669053189283351571920071432553222222811904112119520974410020093306071010335958643236508606549664330684556056421228904824554943559829654154540793885983689462338911148618911233437943092856313175212883771802928968521215461427230178865304889974060408714941809216551397552099050566216607216463931428967751885004128977314044993037370392135272264982092147566078177173327860726953745529225163314733863792635537495622731398807790511518482833382759873192115192207209 +(e1, c1) = (13130317383799359924397818711045172877651070470639872331555061566871077024416132122821689879197166729443692993224787531055068053553245916779683406195947939469930710138275745308571705318328750438377477058341710049450433868075025011970534711610887418427142999431981800104300319735079412330836192720430158369804693687507459455621592955618266507196962663247417904680299143606004651444970274693793668715761929296821908860947834841947073379537992600397854852337772316114987249254395674689638512533430273885970458183044843553777077752747556298072797820716079692849044148071698585069757021266842594074685187380985522959676924, 3276033314700994933236715546269096681595964054694634317877930652961630783669009686295177734678226788913957176667505963284895192875563765999040362544244408645923937742131293085082421535485813399270056524297324864682622089578866968706269063489779845211872503005591066652086230371845356855417702566514946373846876609725394545339840695130518357770158558391396835218039249572390662833461220605497534710914935522013573314984887838699014465554643808438475560847600079478934259045848291858470555503523718530137358192672530066755416937024529536303824075068992110042077005432280129307864841939511235555989308133055235385105960) +(e2, c2) = (20883594128285008437725229014478679601366127938823960100219581029154081635436411892478004501333834114219976189312792835720670788637746570550119467812230092062199251164946197959206350494458367692847308442685450722126282132876286895613925612558140177853699821618151096670620765409968557233259334756429446973833981043722454375455334033442236036896820634662734963958738789068654435207820624411915045062084652483285735900502029367176441696762291709434815865847363600312665970290960775666366786471564595838531305478536744797611070398211876965476639913075928103807981832916853895307250848232566714169131101439494532639396872, 18023359039022070922496207692467909272905633400500071646677663883848372907925575359795644502829612958089930556811098737564701111791300315722656180784065385762079524349557515732188405944474314448560602595952205309214787356604461723684793632495397765839132359663293143446639091410994479947265462557919856471699351934094395015205994443217852376256039110600437586852484006845325143039405449700872936218023776566918818003785468900212143526790175840288515458337112681822830546618062507825380629100313042086810588864941567987823223444256356108148388871548275890051441470007397336976314029406010035567308845594636823378393001) +from math import gcd +p = gcd(N, c1 - c2) +m = (c1 - pow(p, e1, N)) % N +flag = bytes.fromhex(hex(m)[2:]).decode() +print(flag) +``` \ No newline at end of file diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss new file mode 100644 index 0000000..465cb08 --- /dev/null +++ b/_sass/addon/commons.scss @@ -0,0 +1,1542 @@ +/* The common styles */ + +html { + font-size: 16px; + + @media (prefers-color-scheme: light) { + &:not([data-mode]), + &[data-mode='light'] { + @include light-scheme; + } + + &[data-mode='dark'] { + @include dark-scheme; + } + } + + @media (prefers-color-scheme: dark) { + &:not([data-mode]), + &[data-mode='dark'] { + @include dark-scheme; + } + + &[data-mode='light'] { + @include light-scheme; + } + } +} + +body { + background: var(--main-bg); + padding: env(safe-area-inset-top) env(safe-area-inset-right) + env(safe-area-inset-bottom) env(safe-area-inset-left); + color: var(--text-color); + -webkit-font-smoothing: antialiased; + font-family: $font-family-base; +} + +/* --- Typography --- */ + +@for $i from 1 through 5 { + h#{$i} { + @extend %heading; + + @if $i > 1 { + @extend %anchor; + } + + @if $i < 5 { + $size-factor: 0.25rem; + + @if $i > 1 { + $size-factor: 0.18rem; + + main & { + @if $i == 2 { + margin: 2.5rem 0 1.25rem; + } @else { + margin: 2rem 0 1rem; + } + } + } + + & { + font-size: 1rem + (5 - $i) * $size-factor; + } + } @else { + font-size: 1.05rem; + } + } +} + +a { + @extend %link-color; + + text-decoration: none; +} + +img { + max-width: 100%; + height: auto; + transition: all 0.35s ease-in-out; + + .blur & { + $blur: 20px; + + -webkit-filter: blur($blur); + filter: blur($blur); + } +} + +blockquote { + border-left: 0.125rem solid var(--blockquote-border-color); + padding-left: 1rem; + color: var(--blockquote-text-color); + margin-top: 0.5rem; + + > p:last-child { + margin-bottom: 0; + } + + &[class^='prompt-'] { + border-left: 0; + position: relative; + padding: 1rem 1rem 1rem 3rem; + color: var(--prompt-text-color); + + @extend %rounded; + + &::before { + text-align: center; + width: 3rem; + position: absolute; + left: 0.25rem; + margin-top: 0.4rem; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + } + } + + @include prompt('tip', '\f0eb', $fa-style: 'regular'); + @include prompt('info', '\f06a', $rotate: 180); + @include prompt('warning', '\f06a'); + @include prompt('danger', '\f071'); +} + +kbd { + font-family: Lato, sans-serif; + display: inline-block; + vertical-align: middle; + line-height: 1.3rem; + min-width: 1.75rem; + text-align: center; + margin: 0 0.3rem; + padding-top: 0.1rem; + color: var(--kbd-text-color); + background-color: var(--kbd-bg-color); + border-radius: $radius-sm; + border: solid 1px var(--kbd-wrap-color); + box-shadow: inset 0 -2px 0 var(--kbd-wrap-color); +} + +hr { + border-color: var(--main-border-color); + opacity: 1; +} + +footer { + background-color: var(--main-bg); + height: $footer-height; + border-top: 1px solid var(--main-border-color); + + @extend %text-xs; + + a { + @extend %text-highlight; + + &:hover { + @extend %link-hover; + } + } + + em { + @extend %text-highlight; + } + + p { + text-align: center; + margin-bottom: 0; + } +} + +/* fontawesome icons */ +i { + &.far, + &.fas { + @extend %no-cursor; + } +} + +/* --- Panels --- */ + +.access { + top: 2rem; + transition: top 0.2s ease-in-out; + margin-top: 3rem; + margin-bottom: 4rem; + + &:only-child { + position: -webkit-sticky; + position: sticky; + } + + > section { + padding-left: 1rem; + border-left: 1px solid var(--main-border-color); + + &:not(:last-child) { + margin-bottom: 4rem; + } + } + + .content { + font-size: 0.9rem; + } +} + +#panel-wrapper { + /* the headings */ + .panel-heading { + font-family: inherit; + line-height: inherit; + + @include label(inherit); + } + + .post-tag { + line-height: 1.05rem; + font-size: 0.85rem; + border-radius: 0.8rem; + padding: 0.3rem 0.5rem; + margin: 0 0.35rem 0.5rem 0; + + &:hover { + transition: all 0.3s ease-in; + } + } +} + +#access-lastmod { + a { + color: inherit; + + &:hover { + @extend %link-hover; + } + + @extend %no-bottom-border; + } +} + +.footnotes > ol { + padding-left: 2rem; + margin-top: 0.5rem; + + > li { + &:not(:last-child) { + margin-bottom: 0.3rem; + } + + @extend %sup-fn-target; + + > p { + margin-left: 0.25em; + margin-top: 0; + margin-bottom: 0; + } + } +} + +.footnote { + @at-root a#{&} { + @include ml-mr(1px); + @include pl-pr(2px); + + border-bottom-style: none !important; + } +} + +sup { + @extend %sup-fn-target; +} + +.reversefootnote { + @at-root a#{&} { + font-size: 0.6rem; + line-height: 1; + position: relative; + bottom: 0.25em; + margin-left: 0.25em; + border-bottom-style: none !important; + } +} + +/* --- Begin of Markdown table style --- */ + +/* it will be created by Liquid */ +.table-wrapper { + overflow-x: auto; + margin-bottom: 1.5rem; + + > table { + min-width: 100%; + overflow-x: auto; + border-spacing: 0; + + thead { + border-bottom: solid 2px rgba(210, 215, 217, 0.75); + + th { + @extend %table-cell; + } + } + + tbody { + tr { + border-bottom: 1px solid var(--tb-border-color); + + &:nth-child(2n) { + background-color: var(--tb-even-bg); + } + + &:nth-child(2n + 1) { + background-color: var(--tb-odd-bg); + } + + td { + @extend %table-cell; + } + } + } /* tbody */ + } /* table */ +} + +/* --- post --- */ + +.preview-img { + aspect-ratio: 40 / 21; + width: 100%; + height: 100%; + overflow: hidden; + + @extend %rounded; + + &:not(.no-bg) { + background: var(--img-bg); + } + + img { + height: 100%; + -o-object-fit: cover; + object-fit: cover; + + @extend %rounded; + + @at-root #post-list & { + width: 100%; + } + } +} + +.post-preview { + @extend %rounded; + + border: 0; + background: var(--card-bg); + box-shadow: var(--card-shadow); + + &::before { + @extend %rounded; + + content: ''; + width: 100%; + height: 100%; + position: absolute; + background-color: var(--card-hovor-bg); + opacity: 0; + transition: opacity 0.35s ease-in-out; + } + + &:hover { + &::before { + opacity: 0.3; + } + } +} + +main { + line-height: 1.75; + + h1 { + margin-top: 2rem; + } + + p { + > a.popup { + &:not(.normal):not(.left):not(.right) { + @include align-center; + } + } + } + + .categories, + #tags, + #archives { + a:not(:hover) { + @extend %no-bottom-border; + } + } +} + +.post-meta { + @extend %text-sm; + + a { + &:not([class]):hover { + @extend %link-hover; + } + } + + em { + @extend %normal-font-style; + } +} + +.content { + font-size: 1.08rem; + margin-top: 2rem; + overflow-wrap: break-word; + + a { + &.popup { + @extend %no-cursor; + @extend %img-caption; + @include mt-mb(0.5rem); + + cursor: zoom-in; + } + + &:not(.img-link) { + @extend %link-underline; + + &:hover { + @extend %link-hover; + } + } + } + + ol, + ul { + &:not([class]), + &.task-list { + -webkit-padding-start: 1.75rem; + padding-inline-start: 1.75rem; + + li { + margin: 0.25rem 0; + padding-left: 0.25rem; + } + + ol, + ul { + -webkit-padding-start: 1.25rem; + padding-inline-start: 1.25rem; + margin: 0.5rem 0; + } + } + } + + ul.task-list { + -webkit-padding-start: 1.25rem; + padding-inline-start: 1.25rem; + + li { + list-style-type: none; + padding-left: 0; + + /* checkbox icon */ + > i { + width: 2rem; + margin-left: -1.25rem; + color: var(--checkbox-color); + + &.checked { + color: var(--checkbox-checked-color); + } + } + + ul { + -webkit-padding-start: 1.75rem; + padding-inline-start: 1.75rem; + } + } + + input[type='checkbox'] { + margin: 0 0.5rem 0.2rem -1.3rem; + vertical-align: middle; + } + } /* ul */ + + dl > dd { + margin-left: 1rem; + } + + ::marker { + color: var(--text-muted-color); + } +} /* .content */ + +.tag:hover { + @extend %tag-hover; +} + +.post-tag { + display: inline-block; + min-width: 2rem; + text-align: center; + border-radius: 0.5rem; + border: 1px solid var(--btn-border-color); + padding: 0 0.4rem; + color: var(--text-muted-color); + line-height: 1.3rem; + + &:not(:last-child) { + margin-right: 0.2rem; + } +} + +.rounded-10 { + border-radius: 10px !important; +} + +.img-link { + color: transparent; + display: inline-flex; +} + +.shimmer { + overflow: hidden; + position: relative; + background: var(--img-bg); + + &::before { + content: ''; + position: absolute; + background: var(--shimmer-bg); + height: 100%; + width: 100%; + -webkit-animation: shimmer 1.3s infinite; + animation: shimmer 1.3s infinite; + } + + @-webkit-keyframes shimmer { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(100%); + } + } + + @keyframes shimmer { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(100%); + } + } +} + +.embed-video { + width: 100%; + height: 100%; + margin-bottom: 1rem; + aspect-ratio: 16 / 9; + + @extend %rounded; + + &.twitch { + aspect-ratio: 310 / 189; + } + + &.file { + display: block; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + margin: auto; + margin-bottom: 0; + } + + @extend %img-caption; +} + +.embed-audio { + width: 100%; + display: block; + + @extend %img-caption; +} + +/* --- buttons --- */ +.btn-lang { + border: 1px solid !important; + padding: 1px 3px; + border-radius: 3px; + color: var(--link-color); + + &:focus { + box-shadow: none; + } +} + +/* --- Effects classes --- */ + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.btn-box-shadow { + box-shadow: var(--card-shadow); +} + +/* overwrite bootstrap muted */ +.text-muted { + color: var(--text-muted-color) !important; +} + +/* Overwrite bootstrap tooltip */ +.tooltip-inner { + font-size: 0.7rem; + max-width: 220px; + text-align: left; +} + +/* Overwrite bootstrap outline button */ +.btn.btn-outline-primary { + &:not(.disabled):hover { + border-color: #007bff !important; + } +} + +.disabled { + color: rgb(206, 196, 196); + pointer-events: auto; + cursor: not-allowed; +} + +.hide-border-bottom { + border-bottom: none !important; +} + +.input-focus { + box-shadow: none; + border-color: var(--input-focus-border-color) !important; + background: center !important; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} + +.left { + float: left; + margin: 0.75rem 1rem 1rem 0; +} + +.right { + float: right; + margin: 0.75rem 0 1rem 1rem; +} + +/* --- Overriding --- */ + +/* mermaid */ +.mermaid { + text-align: center; +} + +/* MathJax */ +mjx-container { + overflow-y: hidden; + min-width: auto !important; +} + +/* --- sidebar layout --- */ + +$sidebar-display: 'sidebar-display'; +$btn-border-width: 3px; +$btn-mb: 0.5rem; + +#sidebar { + @include pl-pr(0); + + position: fixed; + top: 0; + left: 0; + height: 100%; + overflow-y: auto; + width: $sidebar-width; + z-index: 99; + background: var(--sidebar-bg); + border-right: 1px solid var(--sidebar-border-color); + + /* Hide scrollbar for IE, Edge and Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ + + /* Hide scrollbar for Chrome, Safari and Opera */ + &::-webkit-scrollbar { + display: none; + } + + %sidebar-link-hover { + &:hover { + color: var(--sidebar-active-color); + } + } + + a { + @extend %sidebar-links; + } + + #avatar { + display: block; + width: 7rem; + height: 7rem; + overflow: hidden; + box-shadow: var(--avatar-border-color) 0 0 0 2px; + transform: translateZ(0); /* fixed the zoom in Safari */ + + img { + transition: transform 0.5s; + + &:hover { + transform: scale(1.2); + } + } + } + + .profile-wrapper { + @include mt-mb(2.5rem); + @extend %clickable-transition; + + padding-left: 2.5rem; + padding-right: 1.25rem; + width: 100%; + } + + .site-title { + font-family: inherit; + font-weight: 900; + font-size: 1.75rem; + line-height: 1.2; + letter-spacing: 0.25px; + margin-top: 1.25rem; + margin-bottom: 0.5rem; + + a { + @extend %clickable-transition; + @extend %sidebar-link-hover; + + color: var(--site-title-color); + } + } + + .site-subtitle { + font-size: 95%; + color: var(--site-subtitle-color); + margin-top: 0.25rem; + word-spacing: 1px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + ul { + margin-bottom: 2rem; + + li.nav-item { + opacity: 0.9; + width: 100%; + padding-left: 1.5rem; + padding-right: 1.5rem; + + a.nav-link { + @include pt-pb(0.6rem); + + display: flex; + align-items: center; + border-radius: 0.75rem; + font-weight: 600; + + &:hover { + background-color: var(--sidebar-hover-bg); + } + + i { + font-size: 95%; + opacity: 0.8; + margin-right: 1.5rem; + } + + span { + font-size: 90%; + letter-spacing: 0.2px; + } + } + + &.active { + .nav-link { + color: var(--sidebar-active-color); + background-color: var(--sidebar-hover-bg); + + span { + opacity: 1; + } + } + } + + &:not(:first-child) { + margin-top: 0.25rem; + } + } + } + + .sidebar-bottom { + padding-left: 2rem; + padding-right: 1rem; + margin-bottom: 1.5rem; + + $btn-size: 1.75rem; + + %button { + width: $btn-size; + height: $btn-size; + margin-bottom: $btn-mb; // multi line gap + border-radius: 50%; + color: var(--sidebar-btn-color); + background-color: var(--sidebar-btn-bg); + text-align: center; + display: flex; + align-items: center; + justify-content: center; + + &:not(:focus-visible) { + box-shadow: var(--sidebar-border-color) 0 0 0 1px; + } + + &:hover { + background-color: var(--sidebar-hover-bg); + } + } + + a { + @extend %button; + @extend %sidebar-link-hover; + @extend %clickable-transition; + + &:not(:last-child) { + margin-right: $sb-btn-gap; + } + } + + i { + line-height: $btn-size; + } + + #mode-toggle { + @extend %button; + @extend %sidebar-links; + @extend %sidebar-link-hover; + } + + .icon-border { + @extend %no-cursor; + @include ml-mr(calc(($sb-btn-gap - $btn-border-width) / 2)); + + background-color: var(--sidebar-btn-color); + content: ''; + width: $btn-border-width; + height: $btn-border-width; + border-radius: 50%; + margin-bottom: $btn-mb; + } + } /* .sidebar-bottom */ +} /* #sidebar */ + +@media (hover: hover) { + #sidebar ul > li:last-child::after { + transition: top 0.5s ease; + } + + .nav-link { + transition: background-color 0.3s ease-in-out; + } + + .post-preview { + transition: background-color 0.35s ease-in-out; + } +} + +#search-result-wrapper { + display: none; + height: 100%; + width: 100%; + overflow: auto; + + .content { + margin-top: 2rem; + } +} + +/* --- top-bar --- */ + +#topbar-wrapper { + height: $topbar-height; + background-color: var(--topbar-bg); +} + +#topbar { + button i { + color: #999999; + } + + #breadcrumb { + font-size: 1rem; + color: var(--text-muted-color); + padding-left: 0.5rem; + + a:hover { + @extend %link-hover; + } + + span { + &:not(:last-child) { + &::after { + content: '›'; + padding: 0 0.3rem; + } + } + } + } +} /* #topbar */ + +::-webkit-input-placeholder { + @include placeholder; +} + +::-moz-placeholder { + @include placeholder; +} + +:-ms-input-placeholder { + @include placeholder; +} + +::-ms-input-placeholder { + @include placeholder; +} + +::placeholder { + @include placeholder; +} + +:focus::-webkit-input-placeholder { + @include placeholder-focus; +} + +:focus::-moz-placeholder { + @include placeholder-focus; +} + +:focus:-ms-input-placeholder { + @include placeholder-focus; +} + +:focus::-ms-input-placeholder { + @include placeholder-focus; +} + +:focus::placeholder { + @include placeholder-focus; +} + +search { + display: flex; + width: 100%; + border-radius: 1rem; + border: 1px solid var(--search-border-color); + background: var(--main-bg); + padding: 0 0.5rem; + + i { + z-index: 2; + font-size: 0.9rem; + color: var(--search-icon-color); + } +} + +#sidebar-trigger, +#search-trigger { + display: none; +} + +/* 'Cancel' link */ +#search-cancel { + color: var(--link-color); + display: none; + white-space: nowrap; + + @extend %cursor-pointer; +} + +#search-input { + background: center; + border: 0; + border-radius: 0; + padding: 0.18rem 0.3rem; + color: var(--text-color); + height: auto; + + &:focus { + box-shadow: none; + } +} + +#search-hints { + padding: 0 1rem; + + h4 { + margin-bottom: 1.5rem; + } + + .post-tag { + display: inline-block; + line-height: 1rem; + font-size: 1rem; + background: var(--search-tag-bg); + border: none; + padding: 0.5rem; + margin: 0 1.25rem 1rem 0; + + &::before { + content: '#'; + color: var(--text-muted-color); + padding-right: 0.2rem; + } + + @extend %link-color; + } +} + +#search-results { + padding-bottom: 3rem; + + a { + font-size: 1.4rem; + line-height: 2.5rem; + + &:hover { + @extend %link-hover; + } + + @extend %link-color; + @extend %no-bottom-border; + @extend %heading; + } + + > article { + width: 100%; + + &:not(:last-child) { + margin-bottom: 1rem; + } + + /* icons */ + i { + color: #818182; + margin-right: 0.15rem; + font-size: 80%; + } + + > p { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + } + } +} /* #search-results */ + +#topbar-title { + display: none; + font-size: 1.1rem; + font-weight: 600; + font-family: sans-serif; + color: var(--topbar-text-color); + text-align: center; + width: 70%; + overflow: hidden; + text-overflow: ellipsis; + word-break: keep-all; + white-space: nowrap; +} + +#mask { + display: none; + position: fixed; + inset: 0 0 0 0; + height: 100%; + width: 100%; + z-index: 1; + + @at-root [#{$sidebar-display}] & { + display: block !important; + } +} + +/* --- basic wrappers --- */ + +#main-wrapper { + position: relative; + + @include pl-pr(0); + + > .container { + min-height: 100vh; + } +} + +#topbar-wrapper.row, +#main-wrapper > .container > .row, +#search-result-wrapper > .row { + @include ml-mr(0); +} + +#tail-wrapper { + > :not(script) { + margin-top: 3rem; + } +} + +/* --- button back-to-top --- */ + +#back-to-top { + visibility: hidden; + opacity: 0; + z-index: 1; + cursor: pointer; + position: fixed; + right: 1rem; + bottom: calc($footer-height-large - $back2top-size / 2); + background: var(--button-bg); + color: var(--btn-backtotop-color); + padding: 0; + width: $back2top-size; + height: $back2top-size; + border-radius: 50%; + border: 1px solid var(--btn-backtotop-border-color); + transition: opacity 0.5s ease-in-out, transform 0.2s ease-out; + + &:hover { + transform: translate3d(0, -5px, 0); + -webkit-transform: translate3d(0, -5px, 0); + } + + i { + line-height: $back2top-size; + position: relative; + bottom: 2px; + } + + &.show { + opacity: 1; + visibility: visible; + } +} + +#notification { + @-webkit-keyframes popup { + from { + opacity: 0; + bottom: 0; + } + } + + @keyframes popup { + from { + opacity: 0; + bottom: 0; + } + } + + .toast-header { + background: none; + border-bottom: none; + color: inherit; + } + + .toast-body { + font-family: Lato, sans-serif; + line-height: 1.25rem; + + button { + font-size: 90%; + min-width: 4rem; + } + } + + &.toast { + &.show { + display: block; + min-width: 20rem; + border-radius: 0.5rem; + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + background-color: rgba(255, 255, 255, 0.5); + color: #1b1b1eba; + position: fixed; + left: 50%; + bottom: 20%; + transform: translateX(-50%); + -webkit-animation: popup 0.8s; + animation: popup 0.8s; + } + } +} + +/* + Responsive Design: + + {sidebar, content, panel} >= 1200px screen width + {sidebar, content} >= 850px screen width + {content} <= 849px screen width + +*/ + +@media all and (max-width: 576px) { + main { + .content { + > blockquote[class^='prompt-'] { + @include ml-mr(-1rem); + + border-radius: 0; + max-width: none; + } + } + } + + #avatar { + width: 5rem; + height: 5rem; + } +} + +@media all and (max-width: 768px) { + %full-width { + max-width: 100%; + } + + #topbar { + @extend %full-width; + } + + #main-wrapper > .container { + @extend %full-width; + @include pl-pr(0); + } +} + +/* hide sidebar and panel */ +@media all and (max-width: 849px) { + @mixin slide($append: null) { + $basic: transform 0.4s ease; + + @if $append { + transition: $basic, $append; + } @else { + transition: $basic; + } + } + + footer { + @include slide; + + height: $footer-height-large; + padding: 1.5rem 0; + } + + [#{$sidebar-display}] { + #sidebar { + transform: translateX(0); + } + + #main-wrapper { + transform: translateX($sidebar-width); + } + + #back-to-top { + visibility: hidden; + } + } + + #sidebar { + @include slide; + + transform: translateX(-$sidebar-width); /* hide */ + -webkit-transform: translateX(-$sidebar-width); + } + + #main-wrapper { + @include slide; + } + + #topbar, + #main-wrapper > .container { + max-width: 100%; + } + + #search-result-wrapper { + width: 100%; + } + + #breadcrumb, + search { + display: none; + } + + #topbar-wrapper { + @include slide(top 0.2s ease); + + left: 0; + } + + main, + #panel-wrapper { + margin-top: 0; + } + + #topbar-title, + #sidebar-trigger, + #search-trigger { + display: block; + } + + #search-result-wrapper .content { + letter-spacing: 0; + } + + #tags { + justify-content: center !important; + } + + h1.dynamic-title { + display: none; + + ~ .content { + margin-top: 2.5rem; + } + } +} /* max-width: 849px */ + +/* Sidebar is visible */ +@media all and (min-width: 850px) { + /* Solved jumping scrollbar */ + html { + overflow-y: scroll; + } + + #main-wrapper { + margin-left: $sidebar-width; + } + + #sidebar { + .profile-wrapper { + margin-top: 3rem; + } + } + + #search-hints { + display: none; + } + + search { + max-width: $search-max-width; + } + + #search-result-wrapper { + max-width: $main-content-max-width; + justify-content: start !important; + } + + main { + h1 { + margin-top: 3rem; + } + } + + div.content .table-wrapper > table { + min-width: 70%; + } + + /* button 'back-to-Top' position */ + #back-to-top { + right: 5%; + bottom: calc($footer-height - $back2top-size / 2); + } + + #topbar-title { + text-align: left; + } +} + +/* Pad horizontal */ +@media all and (min-width: 992px) and (max-width: 1199px) { + #main-wrapper > .container .col-lg-11 { + flex: 0 0 96%; + max-width: 96%; + } +} + +/* Compact icons in sidebar & panel hidden */ +@media all and (min-width: 850px) and (max-width: 1199px) { + #search-results > div { + max-width: 700px; + } + + #breadcrumb { + width: 65%; + overflow: hidden; + text-overflow: ellipsis; + word-break: keep-all; + white-space: nowrap; + } +} + +/* panel hidden */ +@media all and (max-width: 1199px) { + #panel-wrapper { + display: none; + } + + #main-wrapper > .container > div.row { + justify-content: center !important; + } +} + +/* --- desktop mode, both sidebar and panel are visible --- */ + +@media all and (min-width: 1200px) { + search { + margin-right: 4rem; + } + + #search-input { + transition: all 0.3s ease-in-out; + } + + #search-results > article { + width: 45%; + + &:nth-child(odd) { + margin-right: 1.5rem; + } + + &:nth-child(even) { + margin-left: 1.5rem; + } + + &:last-child:nth-child(odd) { + position: relative; + right: 24.3%; + } + } + + .content { + font-size: 1.03rem; + } +} + +@media all and (min-width: 1400px) { + #back-to-top { + right: calc((100vw - $sidebar-width - 1140px) / 2 + 3rem); + } +} + +@media all and (min-width: 1650px) { + $icon-gap: 1rem; + + #main-wrapper { + margin-left: $sidebar-width-large; + } + + #topbar-wrapper { + left: $sidebar-width-large; + } + + search { + margin-right: calc( + $main-content-max-width / 4 - $search-max-width - 0.75rem + ); + } + + #main-wrapper > .container { + max-width: $main-content-max-width; + padding-left: 1.75rem !important; + padding-right: 1.75rem !important; + } + + main.col-12, + #tail-wrapper { + padding-right: 4.5rem !important; + } + + #back-to-top { + right: calc( + (100vw - $sidebar-width-large - $main-content-max-width) / 2 + 2rem + ); + } + + #sidebar { + width: $sidebar-width-large; + + .profile-wrapper { + margin-top: 3.5rem; + margin-bottom: 2.5rem; + padding-left: 3.5rem; + } + + ul { + li.nav-item { + @include pl-pr(2.75rem); + } + } + + .sidebar-bottom { + padding-left: 2.75rem; + margin-bottom: 1.75rem; + + a:not(:last-child) { + margin-right: $sb-btn-gap-lg; + } + + .icon-border { + @include ml-mr(calc(($sb-btn-gap-lg - $btn-border-width) / 2)); + } + } + } +} /* min-width: 1650px */ diff --git a/_sass/addon/module.scss b/_sass/addon/module.scss new file mode 100644 index 0000000..42db4e2 --- /dev/null +++ b/_sass/addon/module.scss @@ -0,0 +1,193 @@ +/* +* Mainly scss modules, only imported to `assets/css/main.scss` +*/ + +/* ---------- scss placeholder --------- */ + +%heading { + color: var(--heading-color); + font-weight: 400; + font-family: $font-family-heading; +} + +%anchor { + .anchor { + font-size: 80%; + } + + @media (hover: hover) { + .anchor { + visibility: hidden; + opacity: 0; + transition: opacity 0.25s ease-in, visibility 0s ease-in 0.25s; + } + + &:hover { + .anchor { + visibility: visible; + opacity: 1; + transition: opacity 0.25s ease-in, visibility 0s ease-in 0s; + } + } + } +} + +%tag-hover { + background: var(--tag-hover); + transition: background 0.35s ease-in-out; +} + +%table-cell { + padding: 0.4rem 1rem; + font-size: 95%; + white-space: nowrap; +} + +%link-hover { + color: #d2603a !important; + border-bottom: 1px solid #d2603a; + text-decoration: none; +} + +%link-color { + color: var(--link-color); +} + +%link-underline { + border-bottom: 1px solid var(--link-underline-color); +} + +%clickable-transition { + transition: all 0.3s ease-in-out; +} + +%no-cursor { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +%no-bottom-border { + border-bottom: none; +} + +%cursor-pointer { + cursor: pointer; +} + +%normal-font-style { + font-style: normal; +} + +%rounded { + border-radius: $radius-lg; +} + +%img-caption { + + em { + display: block; + text-align: center; + font-style: normal; + font-size: 80%; + padding: 0; + color: #6d6c6c; + } +} + +%sidebar-links { + color: var(--sidebar-muted-color); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +%text-clip { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +%text-highlight { + color: var(--text-muted-highlight-color); + font-weight: 600; +} + +%text-sm { + font-size: 0.85rem; +} + +%text-xs { + font-size: 0.8rem; +} + +%sup-fn-target { + &:target { + background-color: var(--footnote-target-bg); + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; + transition: background-color 1.75s ease-in-out; + } +} + +/* ---------- scss mixin --------- */ + +@mixin mt-mb($value) { + margin-top: $value; + margin-bottom: $value; +} + +@mixin ml-mr($value) { + margin-left: $value; + margin-right: $value; +} + +@mixin pt-pb($val) { + padding-top: $val; + padding-bottom: $val; +} + +@mixin pl-pr($val) { + padding-left: $val; + padding-right: $val; +} + +@mixin placeholder { + color: var(--text-muted-color) !important; +} + +@mixin placeholder-focus { + opacity: 0.6; +} + +@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) { + color: $color; + font-size: $font-size; + font-weight: $font-weight; +} + +@mixin align-center { + position: relative; + left: 50%; + transform: translateX(-50%); +} + +@mixin prompt($type, $fa-content, $fa-style: 'solid', $rotate: 0) { + &.prompt-#{$type} { + background-color: var(--prompt-#{$type}-bg); + + &::before { + content: $fa-content; + color: var(--prompt-#{$type}-icon-color); + font: var(--fa-font-#{$fa-style}); + + @if $rotate != 0 { + transform: rotate(#{$rotate}deg); + } + } + } +} diff --git a/_sass/addon/syntax.scss b/_sass/addon/syntax.scss new file mode 100644 index 0000000..6bd7b40 --- /dev/null +++ b/_sass/addon/syntax.scss @@ -0,0 +1,292 @@ +/* +* The syntax highlight. +*/ + +@import 'colors/syntax-light'; +@import 'colors/syntax-dark'; + +html { + @media (prefers-color-scheme: light) { + &:not([data-mode]), + &[data-mode='light'] { + @include light-syntax; + } + + &[data-mode='dark'] { + @include dark-syntax; + } + } + + @media (prefers-color-scheme: dark) { + &:not([data-mode]), + &[data-mode='dark'] { + @include dark-syntax; + } + + &[data-mode='light'] { + @include light-syntax; + } + } +} + +/* -- code snippets -- */ + +%code-snippet-bg { + background-color: var(--highlight-bg-color); +} + +%code-snippet-padding { + padding-left: 1rem; + padding-right: 1.5rem; +} + +.highlighter-rouge { + color: var(--highlighter-rouge-color); + margin-top: 0.5rem; + margin-bottom: 1.2em; /* Override BS Inline-code style */ +} + +.highlight { + @extend %rounded; + @extend %code-snippet-bg; + + overflow: auto; + padding-bottom: 0.75rem; + + @at-root figure#{&} { + @extend %code-snippet-bg; + } + + pre { + margin-bottom: 0; + font-size: $code-font-size; + line-height: 1.4rem; + word-wrap: normal; /* Fixed Safari overflow-x */ + } + + table { + td { + &:first-child { + display: inline-block; + margin-left: 1rem; + margin-right: 0.75rem; + } + + &:last-child { + padding-right: 2rem !important; + } + + pre { + overflow: visible; /* Fixed iOS safari overflow-x */ + word-break: normal; /* Fixed iOS safari linenos code break */ + } + } + } + + .lineno { + text-align: right; + color: var(--highlight-lineno-color); + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + -ms-user-select: none; + user-select: none; + } +} /* .highlight */ + +code { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + color: var(--code-color); + + &.highlighter-rouge { + font-size: $code-font-size; + padding: 3px 5px; + word-break: break-word; + border-radius: $radius-sm; + background-color: var(--inline-code-bg); + } + + &.filepath { + background-color: inherit; + color: var(--filepath-text-color); + font-weight: 600; + padding: 0; + } + + a > &.highlighter-rouge { + padding-bottom: 0; /* show link's underlinke */ + color: inherit; + } + + a:hover > &.highlighter-rouge { + border-bottom: none; + } + + blockquote & { + color: inherit; + } +} + +td.rouge-code { + @extend %code-snippet-padding; + + /* + Prevent some browser extends from + changing the URL string of code block. + */ + a { + color: inherit !important; + border-bottom: none !important; + pointer-events: none; + } +} + +div[class^='language-'] { + @extend %rounded; + @extend %code-snippet-bg; + + box-shadow: var(--language-border-color) 0 0 0 1px; + + .content > & { + @include ml-mr(-1rem); + + border-radius: 0; + } + + .highlight { + border-top-left-radius: 0; + border-top-right-radius: 0; + } +} + +/* Hide line numbers for default, console, and terminal code snippets */ +div { + &.nolineno, + &.language-plaintext, + &.language-console, + &.language-terminal { + td:first-child { + padding: 0 !important; + margin-right: 0; + + .lineno { + display: none; + } + } + } +} + +.code-header { + @extend %no-cursor; + + display: flex; + justify-content: space-between; + align-items: center; + height: $code-header-height; + margin-left: 0.75rem; + margin-right: 0.25rem; + + /* the label block */ + span { + line-height: $code-header-height; + + /* label icon */ + i { + font-size: 1rem; + width: $code-icon-width; + color: var(--code-header-icon-color); + + &.small { + font-size: 70%; + } + } + + @at-root [file] #{&} > i { + position: relative; + top: 1px; /* center the file icon */ + } + + /* label text */ + &::after { + content: attr(data-label-text); + font-size: 0.85rem; + font-weight: 600; + color: var(--code-header-text-color); + } + } + + /* clipboard */ + button { + @extend %cursor-pointer; + @extend %rounded; + + border: 1px solid transparent; + height: $code-header-height; + width: $code-header-height; + padding: 0; + background-color: inherit; + + i { + color: var(--code-header-icon-color); + } + + &[timeout] { + &:hover { + border-color: var(--clipboard-checked-color); + } + + i { + color: var(--clipboard-checked-color); + } + } + + &:focus { + outline: none; + } + + &:not([timeout]):hover { + background-color: rgba(128, 128, 128, 0.37); + + i { + color: white; + } + } + } +} + +@media all and (min-width: 576px) { + div[class^='language-'] { + .content > & { + @include ml-mr(0); + + border-radius: $radius-lg; + } + + .code-header { + @include ml-mr(0); + + $dot-margin: 1rem; + + &::before { + content: ''; + display: inline-block; + margin-left: $dot-margin; + width: $code-dot-size; + height: $code-dot-size; + border-radius: 50%; + background-color: var(--code-header-muted-color); + box-shadow: ($code-dot-size + $code-dot-gap) 0 0 + var(--code-header-muted-color), + ($code-dot-size + $code-dot-gap) * 2 0 0 + var(--code-header-muted-color); + } + + span { + // center the text of label + margin-left: calc(($dot-margin + $code-dot-size) / 2 * -1); + } + } + } +} diff --git a/_sass/addon/variables.scss b/_sass/addon/variables.scss new file mode 100644 index 0000000..1d51cb1 --- /dev/null +++ b/_sass/addon/variables.scss @@ -0,0 +1,34 @@ +/* + * The SCSS variables + */ + +/* sidebar */ + +$sidebar-width: 260px !default; /* the basic width */ +$sidebar-width-large: 300px !default; /* screen width: >= 1650px */ +$sb-btn-gap: 0.8rem !default; +$sb-btn-gap-lg: 1rem !default; + +/* other framework sizes */ + +$topbar-height: 3rem !default; +$search-max-width: 200px !default; +$footer-height: 5rem !default; +$footer-height-large: 6rem !default; /* screen width: < 850px */ +$main-content-max-width: 1250px !default; +$radius-sm: 6px !default; +$radius-lg: 10px !default; +$back2top-size: 2.75rem !default; + +/* syntax highlight */ + +$code-font-size: 0.85rem !default; +$code-header-height: 2.25rem !default; +$code-dot-size: 0.75rem !default; +$code-dot-gap: 0.5rem !default; +$code-icon-width: 1.75rem !default; + +/* fonts */ + +$font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif !default; +$font-family-heading: Lato, 'Microsoft Yahei', sans-serif !default; diff --git a/_sass/colors/syntax-dark.scss b/_sass/colors/syntax-dark.scss new file mode 100644 index 0000000..eb92204 --- /dev/null +++ b/_sass/colors/syntax-dark.scss @@ -0,0 +1,164 @@ +/* + * The syntax dark mode styles. + */ + +@mixin dark-syntax { + --language-border-color: #2d2d2d; + --highlight-bg-color: #151515; + --highlighter-rouge-color: #c9def1; + --highlight-lineno-color: #808080; + --inline-code-bg: rgba(255, 255, 255, 0.05); + --code-color: #b0b0b0; + --code-header-text-color: #6a6a6a; + --code-header-muted-color: #353535; + --code-header-icon-color: #565656; + --clipboard-checked-color: #2bcc2b; + --filepath-text-color: #cacaca; + + .highlight .gp { + color: #87939d; + } + + /* --- Syntax highlight theme from `rougify style base16.dark` --- */ + + .highlight table td { + padding: 5px; + } + + .highlight table pre { + margin: 0; + } + + .highlight, + .highlight .w { + color: #d0d0d0; + background-color: #151515; + } + + .highlight .err { + color: #151515; + background-color: #ac4142; + } + + .highlight .c, + .highlight .ch, + .highlight .cd, + .highlight .cm, + .highlight .cpf, + .highlight .c1, + .highlight .cs { + color: #848484; + } + + .highlight .cp { + color: #f4bf75; + } + + .highlight .nt { + color: #f4bf75; + } + + .highlight .o, + .highlight .ow { + color: #d0d0d0; + } + + .highlight .p, + .highlight .pi { + color: #d0d0d0; + } + + .highlight .gi { + color: #90a959; + } + + .highlight .gd { + color: #f08a8b; + background-color: #320000; + } + + .highlight .gh { + color: #6a9fb5; + background-color: #151515; + font-weight: bold; + } + + .highlight .k, + .highlight .kn, + .highlight .kp, + .highlight .kr, + .highlight .kv { + color: #aa759f; + } + + .highlight .kc { + color: #d28445; + } + + .highlight .kt { + color: #d28445; + } + + .highlight .kd { + color: #d28445; + } + + .highlight .s, + .highlight .sb, + .highlight .sc, + .highlight .dl, + .highlight .sd, + .highlight .s2, + .highlight .sh, + .highlight .sx, + .highlight .s1 { + color: #90a959; + } + + .highlight .sa { + color: #aa759f; + } + + .highlight .sr { + color: #75b5aa; + } + + .highlight .si { + color: #b76d45; + } + + .highlight .se { + color: #b76d45; + } + + .highlight .nn { + color: #f4bf75; + } + + .highlight .nc { + color: #f4bf75; + } + + .highlight .no { + color: #f4bf75; + } + + .highlight .na { + color: #6a9fb5; + } + + .highlight .m, + .highlight .mb, + .highlight .mf, + .highlight .mh, + .highlight .mi, + .highlight .il, + .highlight .mo, + .highlight .mx { + color: #90a959; + } + + .highlight .ss { + color: #90a959; + } +} diff --git a/_sass/colors/syntax-light.scss b/_sass/colors/syntax-light.scss new file mode 100644 index 0000000..76aa669 --- /dev/null +++ b/_sass/colors/syntax-light.scss @@ -0,0 +1,210 @@ +/* + * The syntax light mode code snippet colors. + */ + +@mixin light-syntax { + /* --- custom light colors --- */ + --language-border-color: #ececec; + --highlight-bg-color: #f6f8fa; + --highlighter-rouge-color: #3f596f; + --highlight-lineno-color: #9e9e9e; + --inline-code-bg: rgba(25, 25, 28, 0.05); + --code-color: #3a3a3a; + --code-header-text-color: #a3a3a3; + --code-header-muted-color: #e5e5e5; + --code-header-icon-color: #c9c8c8; + --clipboard-checked-color: #43c743; + + /* --- Syntax highlight theme from `rougify style github` --- */ + + .highlight table td { + padding: 5px; + } + + .highlight table pre { + margin: 0; + } + + .highlight, + .highlight .w { + color: #24292f; + background-color: #f6f8fa; + } + + .highlight .k, + .highlight .kd, + .highlight .kn, + .highlight .kp, + .highlight .kr, + .highlight .kt, + .highlight .kv { + color: #cf222e; + } + + .highlight .gr { + color: #f6f8fa; + } + + .highlight .gd { + color: #82071e; + background-color: #ffebe9; + } + + .highlight .nb { + color: #953800; + } + + .highlight .nc { + color: #953800; + } + + .highlight .no { + color: #953800; + } + + .highlight .nn { + color: #953800; + } + + .highlight .sr { + color: #116329; + } + + .highlight .na { + color: #116329; + } + + .highlight .nt { + color: #116329; + } + + .highlight .gi { + color: #116329; + background-color: #dafbe1; + } + + .highlight .kc { + color: #0550ae; + } + + .highlight .l, + .highlight .ld, + .highlight .m, + .highlight .mb, + .highlight .mf, + .highlight .mh, + .highlight .mi, + .highlight .il, + .highlight .mo, + .highlight .mx { + color: #0550ae; + } + + .highlight .sb { + color: #0550ae; + } + + .highlight .bp { + color: #0550ae; + } + + .highlight .ne { + color: #0550ae; + } + + .highlight .nl { + color: #0550ae; + } + + .highlight .py { + color: #0550ae; + } + + .highlight .nv, + .highlight .vc, + .highlight .vg, + .highlight .vi, + .highlight .vm { + color: #0550ae; + } + + .highlight .o, + .highlight .ow { + color: #0550ae; + } + + .highlight .gh { + color: #0550ae; + font-weight: bold; + } + + .highlight .gu { + color: #0550ae; + font-weight: bold; + } + + .highlight .s, + .highlight .sa, + .highlight .sc, + .highlight .dl, + .highlight .sd, + .highlight .s2, + .highlight .se, + .highlight .sh, + .highlight .sx, + .highlight .s1, + .highlight .ss { + color: #0a3069; + } + + .highlight .nd { + color: #8250df; + } + + .highlight .nf, + .highlight .fm { + color: #8250df; + } + + .highlight .err { + color: #f6f8fa; + background-color: #82071e; + } + + .highlight .c, + .highlight .ch, + .highlight .cd, + .highlight .cm, + .highlight .cp, + .highlight .cpf, + .highlight .c1, + .highlight .cs { + color: #68717a; + } + + .highlight .gl { + color: #68717a; + } + + .highlight .gt { + color: #68717a; + } + + .highlight .ni { + color: #24292f; + } + + .highlight .si { + color: #24292f; + } + + .highlight .ge { + color: #24292f; + font-style: italic; + } + + .highlight .gs { + color: #24292f; + font-weight: bold; + } +} /* light-syntax */ diff --git a/_sass/colors/typography-dark.scss b/_sass/colors/typography-dark.scss new file mode 100644 index 0000000..75097fc --- /dev/null +++ b/_sass/colors/typography-dark.scss @@ -0,0 +1,147 @@ +/* + * The main dark mode styles + */ + +@mixin dark-scheme { + /* Framework color */ + --main-bg: rgb(27, 27, 30); + --mask-bg: rgb(68, 69, 70); + --main-border-color: rgb(44, 45, 45); + + /* Common color */ + --text-color: rgb(175, 176, 177); + --text-muted-color: #868686; + --text-muted-highlight-color: #aeaeae; + --heading-color: #cccccc; + --label-color: #a7a7a7; + --blockquote-border-color: rgb(66, 66, 66); + --blockquote-text-color: #868686; + --link-color: rgba(213,84,0,255); + --link-underline-color: rgb(82, 108, 150); + --button-bg: #1e1e1e; + --btn-border-color: #2e2f31; + --btn-backtotop-color: var(--text-color); + --btn-backtotop-border-color: #212122; + --btn-box-shadow: var(--main-bg); + --card-header-bg: #292929; + --checkbox-color: rgb(118, 120, 121); + --checkbox-checked-color: var(--link-color); + --img-bg: radial-gradient(circle, rgb(22, 22, 24) 0%, rgb(32, 32, 32) 100%); + --shimmer-bg: linear-gradient( + 90deg, + rgba(255, 255, 255, 0) 0%, + rgba(58, 55, 55, 0.4) 50%, + rgba(255, 255, 255, 0) 100% + ); + + /* Sidebar */ + --site-title-color: #717070; + --site-subtitle-color: #868686; + --sidebar-bg: #1e1e1e; + --sidebar-border-color: #292929; + --sidebar-muted-color: #868686; + --sidebar-active-color: rgba(213,84,0,255); + --sidebar-hover-bg: #262626; + --sidebar-btn-bg: #232328; + --sidebar-btn-color: #787878; + --avatar-border-color: rgb(206, 206, 206, 0.9); + + /* Topbar */ + --topbar-bg: rgb(27, 27, 30, 0.64); + --topbar-text-color: var(--text-color); + --search-border-color: rgb(55, 55, 55); + --search-icon-color: rgb(100, 102, 105); + --input-focus-border-color: rgb(112, 114, 115); + + /* Home page */ + --post-list-text-color: rgb(175, 176, 177); + --btn-patinator-text-color: var(--text-color); + --btn-paginator-hover-color: #2e2e2e; + + /* Posts */ + --toc-highlight: rgb(116, 178, 243); + --tag-hover: rgb(43, 56, 62); + --tb-odd-bg: #252526; /* odd rows of the posts' table */ + --tb-even-bg: rgb(31, 31, 34); /* even rows of the posts' table */ + --tb-border-color: var(--tb-odd-bg); + --footnote-target-bg: rgb(63, 81, 181); + --btn-share-color: #6c757d; + --btn-share-hover-color: #bfc1ca; + --card-bg: #1e1e1e; + --card-hovor-bg: #464d51; + --card-shadow: rgb(21, 21, 21, 0.72) 0 6px 18px 0, + rgb(137, 135, 135, 0.24) 0 0 0 1px; + --kbd-wrap-color: #6a6a6a; + --kbd-text-color: #d3d3d3; + --kbd-bg-color: #242424; + --prompt-text-color: rgb(216, 212, 212, 0.75); + --prompt-tip-bg: rgb(22, 60, 36, 0.64); + --prompt-tip-icon-color: rgb(15, 164, 15, 0.81); + --prompt-info-bg: rgb(7, 59, 104, 0.8); + --prompt-info-icon-color: #0075d1; + --prompt-warning-bg: rgb(90, 69, 3, 0.88); + --prompt-warning-icon-color: rgb(255, 165, 0, 0.8); + --prompt-danger-bg: rgb(86, 28, 8, 0.8); + --prompt-danger-icon-color: #cd0202; + + /* Tags */ + --tag-border: rgb(59, 79, 88); + --tag-shadow: rgb(32, 33, 33); + --dash-color: rgb(63, 65, 68); + --search-tag-bg: #292828; + + /* Categories */ + --categories-border: rgb(64, 66, 69, 0.5); + --categories-hover-bg: rgb(73, 75, 76); + --categories-icon-hover-color: white; + + /* Archive */ + --timeline-node-bg: rgb(150, 152, 156); + --timeline-color: rgb(63, 65, 68); + --timeline-year-dot-color: var(--timeline-color); + + color-scheme: dark; + + .light { + display: none; + } + + /* Categories */ + .categories.card, + .list-group-item { + background-color: var(--card-bg); + } + + .categories { + .card-header { + background-color: var(--card-header-bg); + } + + .list-group-item { + border-left: none; + border-right: none; + padding-left: 2rem; + border-color: var(--categories-border); + + &:last-child { + border-bottom-color: var(--card-bg); + } + } + } + + #archives li:nth-child(odd) { + background-image: linear-gradient( + to left, + rgb(26, 26, 30), + rgb(39, 39, 45), + rgb(39, 39, 45), + rgb(39, 39, 45), + rgb(26, 26, 30) + ); + } + + /* stylelint-disable-next-line selector-id-pattern */ + #disqus_thread { + color-scheme: none; + } +} /* dark-scheme */ diff --git a/_sass/colors/typography-light.scss b/_sass/colors/typography-light.scss new file mode 100644 index 0000000..0bf0388 --- /dev/null +++ b/_sass/colors/typography-light.scss @@ -0,0 +1,112 @@ +/* + * The syntax light mode typography colors + */ + +@mixin light-scheme { + /* Framework color */ + --main-bg: white; + --mask-bg: #c1c3c5; + --main-border-color: #f3f3f3; + + /* Common color */ + --text-color: #34343c; + --text-muted-color: #757575; + --text-muted-highlight-color: inherit; + --heading-color: #2a2a2a; + --label-color: #585858; + --blockquote-border-color: #eeeeee; + --blockquote-text-color: #757575; + --link-color: #0056b2; + --link-underline-color: #dee2e6; + --button-bg: #ffffff; + --btn-border-color: #e9ecef; + --btn-backtotop-color: #686868; + --btn-backtotop-border-color: #f1f1f1; + --btn-box-shadow: #eaeaea; + --checkbox-color: #c5c5c5; + --checkbox-checked-color: #07a8f7; + --img-bg: radial-gradient( + circle, + rgb(255, 255, 255) 0%, + rgb(239, 239, 239) 100% + ); + --shimmer-bg: linear-gradient( + 90deg, + rgba(250, 250, 250, 0) 0%, + rgba(232, 230, 230, 1) 50%, + rgba(250, 250, 250, 0) 100% + ); + + /* Sidebar */ + --site-title-color: rgba(213,84,0,255); + --site-subtitle-color: #717171; + --sidebar-bg: #f6f8fa; + --sidebar-border-color: #efefef; + --sidebar-muted-color: #545454; + --sidebar-active-color: #1d1d1d; + --sidebar-hover-bg: rgb(223, 233, 241, 0.64); + --sidebar-btn-bg: white; + --sidebar-btn-color: #8e8e8e; + --avatar-border-color: white; + + /* Topbar */ + --topbar-bg: rgb(255, 255, 255, 0.7); + --topbar-text-color: rgb(78, 78, 78); + --search-border-color: rgb(240, 240, 240); + --search-icon-color: #c2c6cc; + --input-focus-border-color: #b8b8b8; + + /* Home page */ + --post-list-text-color: dimgray; + --btn-patinator-text-color: #555555; + --btn-paginator-hover-color: var(--sidebar-bg); + + /* Posts */ + --toc-highlight: #0550ae; + --btn-share-color: gray; + --btn-share-hover-color: #0d6efd; + --card-bg: white; + --card-hovor-bg: #e2e2e2; + --card-shadow: rgb(104, 104, 104, 0.05) 0 2px 6px 0, + rgba(211, 209, 209, 0.15) 0 0 0 1px; + --footnote-target-bg: lightcyan; + --tb-odd-bg: #fbfcfd; + --tb-border-color: #eaeaea; + --dash-color: silver; + --kbd-wrap-color: #bdbdbd; + --kbd-text-color: var(--text-color); + --kbd-bg-color: white; + --prompt-text-color: rgb(46, 46, 46, 0.77); + --prompt-tip-bg: rgb(123, 247, 144, 0.2); + --prompt-tip-icon-color: #03b303; + --prompt-info-bg: #e1f5fe; + --prompt-info-icon-color: #0070cb; + --prompt-warning-bg: rgb(255, 243, 205); + --prompt-warning-icon-color: #ef9c03; + --prompt-danger-bg: rgb(248, 215, 218, 0.56); + --prompt-danger-icon-color: #df3c30; + + /* Tags */ + --tag-border: #dee2e6; + --tag-shadow: var(--btn-border-color); + --tag-hover: rgb(222, 226, 230); + --search-tag-bg: #f8f9fa; + + /* Categories */ + --categories-border: rgba(0, 0, 0, 0.125); + --categories-hover-bg: var(--btn-border-color); + --categories-icon-hover-color: darkslategray; + + /* Archive */ + --timeline-color: rgba(0, 0, 0, 0.075); + --timeline-node-bg: #c2c6cc; + --timeline-year-dot-color: #ffffff; + + [class^='prompt-'] { + --link-underline-color: rgb(219, 216, 216); + } + + .dark { + display: none; + } +} /* light-scheme */ diff --git a/_sass/layout/archives.scss b/_sass/layout/archives.scss new file mode 100644 index 0000000..3a2e86b --- /dev/null +++ b/_sass/layout/archives.scss @@ -0,0 +1,144 @@ +/* + Style for Archives +*/ + +#archives { + letter-spacing: 0.03rem; + + $timeline-width: 4px; + + %timeline { + content: ''; + width: $timeline-width; + position: relative; + float: left; + background-color: var(--timeline-color); + } + + .year { + height: 3.5rem; + font-size: 1.5rem; + position: relative; + left: 2px; + margin-left: -$timeline-width; + + &::before { + @extend %timeline; + + height: 72px; + left: 79px; + bottom: 16px; + } + + &:first-child::before { + @extend %timeline; + + height: 32px; + top: 24px; + } + + /* Year dot */ + &::after { + content: ''; + display: inline-block; + position: relative; + border-radius: 50%; + width: 12px; + height: 12px; + left: 21.5px; + border: 3px solid; + background-color: var(--timeline-year-dot-color); + border-color: var(--timeline-node-bg); + box-shadow: 0 0 2px 0 #c2c6cc; + z-index: 1; + } + } + + ul { + li { + font-size: 1.1rem; + line-height: 3rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:nth-child(odd) { + background-color: var(--main-bg, #ffffff); + background-image: linear-gradient( + to left, + #ffffff, + #fbfbfb, + #fbfbfb, + #fbfbfb, + #ffffff + ); + } + + &::before { + @extend %timeline; + + top: 0; + left: 77px; + height: 3.1rem; + } + } + + &:last-child li:last-child::before { + height: 1.5rem; + } + } /* #archives ul */ + + .date { + white-space: nowrap; + display: inline-block; + position: relative; + right: 0.5rem; + + &.month { + width: 1.4rem; + text-align: center; + } + + &.day { + font-size: 85%; + font-family: Lato, sans-serif; + } + } + + a { + /* post title in Archvies */ + margin-left: 2.5rem; + position: relative; + top: 0.1rem; + + &:hover { + border-bottom: none; + } + + &::before { + /* the dot before post title */ + content: ''; + display: inline-block; + position: relative; + border-radius: 50%; + width: 8px; + height: 8px; + float: left; + top: 1.35rem; + left: 71px; + background-color: var(--timeline-node-bg); + box-shadow: 0 0 3px 0 #c2c6cc; + z-index: 1; + } + } +} /* #archives */ + +@media all and (max-width: 576px) { + #archives { + margin-top: -1rem; + + ul { + letter-spacing: 0; + } + } +} diff --git a/_sass/layout/categories.scss b/_sass/layout/categories.scss new file mode 100644 index 0000000..f12b963 --- /dev/null +++ b/_sass/layout/categories.scss @@ -0,0 +1,83 @@ +/* + Style for Tab Categories +*/ + +%category-icon-color { + color: gray; +} + +.categories { + margin-bottom: 2rem; + border-color: var(--categories-border); + + &.card, + .list-group { + @extend %rounded; + } + + .card-header { + $radius: calc($radius-lg - 1px); + + padding: 0.75rem; + border-radius: $radius; + border-bottom: 0; + + &.hide-border-bottom { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } + + i { + @extend %category-icon-color; + + font-size: 86%; /* fontawesome icons */ + } + + .list-group-item { + border-left: none; + border-right: none; + padding-left: 2rem; + + &:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + &:last-child { + border-bottom: 0; + } + } +} /* .categories */ + +.category-trigger { + width: 1.7rem; + height: 1.7rem; + border-radius: 50%; + text-align: center; + color: #6c757d !important; + + i { + position: relative; + height: 0.7rem; + width: 1rem; + transition: transform 300ms ease; + } + + &:hover { + i { + color: var(--categories-icon-hover-color); + } + } +} + +/* only works on desktop */ +@media (hover: hover) { + .category-trigger:hover { + background-color: var(--categories-hover-bg); + } +} + +.rotate { + transform: rotate(-90deg); +} diff --git a/_sass/layout/category-tag.scss b/_sass/layout/category-tag.scss new file mode 100644 index 0000000..9e43a91 --- /dev/null +++ b/_sass/layout/category-tag.scss @@ -0,0 +1,72 @@ +/* + Style for page Category and Tag +*/ + +.dash { + margin: 0 0.5rem 0.6rem 0.5rem; + border-bottom: 2px dotted var(--dash-color); +} + +#page-category, +#page-tag { + ul > li { + line-height: 1.5rem; + padding: 0.6rem 0; + + /* dot */ + &::before { + background: #999999; + width: 5px; + height: 5px; + border-radius: 50%; + display: block; + content: ''; + position: relative; + top: 0.6rem; + margin-right: 0.5rem; + } + + /* post's title */ + > a { + @extend %no-bottom-border; + + font-size: 1.1rem; + } + } +} + +/* tag icon */ +#page-tag h1 > i { + font-size: 1.2rem; +} + +#page-category h1 > i { + font-size: 1.25rem; +} + +#page-category, +#page-tag, +#access-lastmod { + a:hover { + @extend %link-hover; + + margin-bottom: -1px; /* Avoid jumping */ + } +} + +@media all and (max-width: 576px) { + #page-category, + #page-tag { + ul > li { + &::before { + margin: 0 0.5rem; + } + + > a { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} diff --git a/_sass/layout/home.scss b/_sass/layout/home.scss new file mode 100644 index 0000000..0d95d7b --- /dev/null +++ b/_sass/layout/home.scss @@ -0,0 +1,189 @@ +/* + Style for Homepage +*/ + +#post-list { + margin-top: 2rem; + + .card-wrapper { + &:hover { + text-decoration: none; + } + + &:not(:last-child) { + margin-bottom: 1.25rem; + } + } + + .card { + border: 0; + background: none; + + %img-radius { + border-radius: $radius-lg $radius-lg 0 0; + } + + .preview-img { + @extend %img-radius; + + img { + @extend %img-radius; + } + } + + .card-body { + height: 100%; + padding: 1rem; + + .card-title { + @extend %text-clip; + + color: var(--heading-color) !important; + font-size: 1.25rem; + } + + %muted { + color: var(--text-muted-color) !important; + } + + .card-text.content { + @extend %muted; + + p { + @extend %text-clip; + + line-height: 1.5; + margin: 0; + } + } + + .post-meta { + @extend %muted; + + i { + &:not(:first-child) { + margin-left: 1.5rem; + } + } + + em { + @extend %normal-font-style; + + color: inherit; + } + + > div:first-child { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } + } +} /* #post-list */ + +.pagination { + color: var(--text-color); + font-family: Lato, sans-serif; + justify-content: space-evenly; + + a:hover { + text-decoration: none; + } + + .page-item { + .page-link { + color: var(--btn-patinator-text-color); + padding: 0 0.6rem; + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + border-radius: 0.5rem; + border: 0; + background-color: inherit; + } + + &.active { + .page-link { + background-color: var(--btn-paginator-hover-color); + } + } + + &:not(.active) { + .page-link { + &:hover { + box-shadow: inset var(--btn-border-color) 0 0 0 1px; + } + } + } + + &.disabled { + cursor: not-allowed; + + .page-link { + color: rgba(108, 117, 125, 0.57); + } + } + } /* .page-item */ +} /* .pagination */ + +/* Tablet */ +@media all and (min-width: 768px) { + %img-radius { + border-radius: 0 $radius-lg $radius-lg 0; + } + + #post-list { + .card { + .card-body { + padding: 1.75rem 1.75rem 1.25rem 1.75rem; + + .card-text { + display: inherit !important; + } + + .post-meta { + i { + &:not(:first-child) { + margin-left: 1.75rem; + } + } + } + } + } + } +} + +/* Hide SideBar and TOC */ +@media all and (max-width: 830px) { + .pagination { + .page-item { + &:not(:first-child):not(:last-child) { + display: none; + } + } + } +} + +/* Sidebar is visible */ +@media all and (min-width: 831px) { + #post-list { + margin-top: 2.5rem; + } + + .pagination { + font-size: 0.85rem; + justify-content: center; + + .page-item { + &:not(:last-child) { + margin-right: 0.7rem; + } + } + + .page-index { + display: none; + } + } /* .pagination */ +} diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss new file mode 100644 index 0000000..815db93 --- /dev/null +++ b/_sass/layout/post.scss @@ -0,0 +1,370 @@ +/* + Post-specific style +*/ + +%btn-post-nav { + width: 50%; + position: relative; + border-color: var(--btn-border-color); +} + +@mixin dot($pl: 0.25rem, $pr: 0.25rem) { + content: '\2022'; + padding-left: $pl; + padding-right: $pr; +} + +header { + .post-desc { + @extend %heading; + + font-size: 1.125rem; + line-height: 1.6; + } + + .post-meta { + span + span::before { + @include dot; + } + + em, + time { + @extend %text-highlight; + } + + em { + a { + color: inherit; + } + } + } + + h1 + .post-meta { + margin-top: 1.5rem; + } +} + +.post-tail-wrapper { + @extend %text-sm; + + margin-top: 6rem; + border-bottom: 1px double var(--main-border-color); + + .license-wrapper { + line-height: 1.2rem; + + > a { + @extend %text-highlight; + + &:hover { + @extend %link-hover; + } + } + + span:last-child { + @extend %text-sm; + } + } /* .license-wrapper */ + + .post-meta a:not(:hover) { + @extend %link-underline; + } + + .share-wrapper { + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + %icon-size { + font-size: 1.125rem; + } + + .share-icons { + display: flex; + + i { + color: var(--btn-share-color); + + @extend %icon-size; + } + + > * { + @extend %icon-size; + + margin-left: 0.5rem; + + &:hover { + i { + @extend %btn-share-hovor; + } + } + } + + button { + padding: 0; + border: none; + line-height: inherit; + + @extend %cursor-pointer; + } + } /* .share-icons */ + } /* .share-wrapper */ +} + +.share-mastodon { + /* See: https://github.com/justinribeiro/share-to-mastodon#properties */ + --wc-stm-font-family: $font-family-base; + --wc-stm-dialog-background-color: var(--card-bg); + --wc-stm-form-button-border: 1px solid var(--btn-border-color); + --wc-stm-form-submit-background-color: var(--sidebar-btn-bg); + --wc-stm-form-cancel-background-color: var(--sidebar-btn-bg); + --wc-stm-form-button-background-color-hover: #007bff; + --wc-stm-form-button-color-hover: white; + + font-size: 1rem; +} + +.post-tags { + line-height: 2rem; + + .post-tag { + &:hover { + @extend %link-hover; + @extend %tag-hover; + @extend %no-bottom-border; + } + } +} + +.post-navigation { + .btn { + @extend %btn-post-nav; + + &:not(:hover) { + color: var(--link-color); + } + + &:hover { + &:not(.disabled)::before { + color: whitesmoke; + } + } + + &.disabled { + @extend %btn-post-nav; + + pointer-events: auto; + cursor: not-allowed; + background: none; + color: gray; + } + + &.btn-outline-primary.disabled:focus { + box-shadow: none; + } + + &::before { + color: var(--text-muted-color); + font-size: 0.65rem; + text-transform: uppercase; + content: attr(aria-label); + } + + &:first-child { + border-radius: $radius-lg 0 0 $radius-lg; + left: 0.5px; + } + + &:last-child { + border-radius: 0 $radius-lg $radius-lg 0; + right: 0.5px; + } + } + + p { + font-size: 1.1rem; + line-height: 1.5rem; + margin-top: 0.3rem; + white-space: normal; + } +} /* .post-navigation */ + +@media (hover: hover) { + .post-navigation { + .btn, + .btn::before { + transition: all 0.35s ease-in-out; + } + } +} + +@-webkit-keyframes fade-up { + from { + opacity: 0; + position: relative; + top: 2rem; + } + + to { + opacity: 1; + position: relative; + top: 0; + } +} + +@keyframes fade-up { + from { + opacity: 0; + position: relative; + top: 2rem; + } + + to { + opacity: 1; + position: relative; + top: 0; + } +} + +#toc-wrapper { + border-left: 1px solid rgba(158, 158, 158, 0.17); + position: -webkit-sticky; + position: sticky; + top: 4rem; + transition: top 0.2s ease-in-out; + -webkit-animation: fade-up 0.8s; + animation: fade-up 0.8s; + + ul { + list-style: none; + font-size: 0.85rem; + line-height: 1.25; + padding-left: 0; + + li { + &:not(:last-child) { + margin: 0.4rem 0; + } + + a { + padding: 0.2rem 0 0.2rem 1.25rem; + } + } + + /* Overwrite TOC plugin style */ + + .toc-link { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:hover { + color: var(--toc-highlight); + text-decoration: none; + } + + &::before { + display: none; + } + } + + .is-active-link { + color: var(--toc-highlight) !important; + font-weight: 600; + + &::before { + display: inline-block; + width: 1px; + left: -1px; + height: 1.25rem; + background-color: var(--toc-highlight) !important; + } + } + + ul { + padding-left: 0.75rem; + } + } +} + +/* --- Related Posts --- */ + +#related-posts { + > h3 { + @include label(1.1rem, 600); + } + + time { + @extend %normal-font-style; + @extend %text-xs; + + color: var(--text-muted-color); + } + + p { + font-size: 0.9rem; + margin-bottom: 0.5rem; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + + .card { + h4 { + @extend %text-clip; + } + } +} + +/* stylelint-disable-next-line selector-id-pattern */ +#disqus_thread { + min-height: 8.5rem; +} + +.utterances { + max-width: 100%; +} + +%btn-share-hovor { + color: var(--btn-share-hover-color) !important; +} + +.share-label { + @include label(inherit, 400, inherit); + + &::after { + content: ':'; + } +} + +@media all and (max-width: 576px) { + .post-tail-bottom { + flex-wrap: wrap-reverse !important; + + > div:first-child { + width: 100%; + margin-top: 1rem; + } + } +} + +@media all and (max-width: 768px) { + .content > p > img { + max-width: calc(100% + 1rem); + } +} + +/* Hide SideBar and TOC */ +@media all and (max-width: 849px) { + .post-navigation { + padding-left: 0; + padding-right: 0; + margin-left: -0.5rem; + margin-right: -0.5rem; + } +} diff --git a/_sass/layout/tags.scss b/_sass/layout/tags.scss new file mode 100644 index 0000000..4cf5d3b --- /dev/null +++ b/_sass/layout/tags.scss @@ -0,0 +1,19 @@ +/* + Styles for Tab Tags +*/ + +.tag { + border-radius: 0.7em; + padding: 6px 8px 7px; + margin-right: 0.8rem; + line-height: 3rem; + letter-spacing: 0; + border: 1px solid var(--tag-border) !important; + box-shadow: 0 0 3px 0 var(--tag-shadow); + + span { + margin-left: 0.6em; + font-size: 0.7em; + font-family: Oswald, sans-serif; + } +} diff --git a/_sass/main.bundle.scss b/_sass/main.bundle.scss new file mode 100644 index 0000000..52e893f --- /dev/null +++ b/_sass/main.bundle.scss @@ -0,0 +1,2 @@ +@import 'dist/bootstrap'; +@import 'main'; diff --git a/_sass/main.scss b/_sass/main.scss new file mode 100644 index 0000000..1c2311d --- /dev/null +++ b/_sass/main.scss @@ -0,0 +1,13 @@ +@import 'colors/typography-light'; +@import 'colors/typography-dark'; +@import 'addon/variables'; +@import 'variables-hook'; +@import 'addon/module'; +@import 'addon/syntax'; +@import 'addon/commons'; +@import 'layout/home'; +@import 'layout/post'; +@import 'layout/tags'; +@import 'layout/archives'; +@import 'layout/categories'; +@import 'layout/category-tag'; diff --git a/_sass/variables-hook.scss b/_sass/variables-hook.scss new file mode 100644 index 0000000..f27e0eb --- /dev/null +++ b/_sass/variables-hook.scss @@ -0,0 +1,3 @@ +/* + Appending custom SCSS variables will override the default ones in `_sass/addon/variables.scsss` +*/ diff --git a/_tabs/about.md b/_tabs/about.md index ffb8cb4..af6e2dc 100644 --- a/_tabs/about.md +++ b/_tabs/about.md @@ -1,7 +1,7 @@ --- # the default layout is 'page' icon: fas fa-info-circle -order: 4 +order: 5 ---

Hi 👋, I'm InfernoSAlex

diff --git a/_tabs/archives.md b/_tabs/archives.md index c3abc59..eb89f59 100644 --- a/_tabs/archives.md +++ b/_tabs/archives.md @@ -1,5 +1,5 @@ --- layout: archives icon: fas fa-archive -order: 3 +order: 4 --- diff --git a/_tabs/categories.md b/_tabs/categories.md index 2d241be..0a3c10a 100644 --- a/_tabs/categories.md +++ b/_tabs/categories.md @@ -1,5 +1,5 @@ --- layout: categories icon: fas fa-stream -order: 1 +order: 2 --- diff --git a/_tabs/projects.md b/_tabs/projects.md new file mode 100644 index 0000000..bcec8b9 --- /dev/null +++ b/_tabs/projects.md @@ -0,0 +1,8 @@ +--- +layout: projects +icon: fa-fw fas fa-flask +order: 1 +--- + + +Here, I will post some of the projects I have worked on. \ No newline at end of file diff --git a/_tabs/tags.md b/_tabs/tags.md index ded3adc..fe3da5a 100644 --- a/_tabs/tags.md +++ b/_tabs/tags.md @@ -1,5 +1,5 @@ --- layout: tags icon: fas fa-tags -order: 2 +order: 3 --- diff --git a/_tabs/test.md b/_tabs/test.md deleted file mode 100644 index 1a3dc50..0000000 --- a/_tabs/test.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -order: 6 ---- - - -{% include test.html %} diff --git a/assets/img/logos/cyberedu.png b/assets/img/logos/cyberedu.png new file mode 100644 index 0000000..7984280 Binary files /dev/null and b/assets/img/logos/cyberedu.png differ diff --git a/assets/img/logos/htb/htb-crypto.png b/assets/img/logos/htb/htb-crypto.png new file mode 100644 index 0000000..d6f4806 Binary files /dev/null and b/assets/img/logos/htb/htb-crypto.png differ diff --git a/assets/img/logos/htb/htb-misc.png b/assets/img/logos/htb/htb-misc.png index ea3c72f..f814973 100644 Binary files a/assets/img/logos/htb/htb-misc.png and b/assets/img/logos/htb/htb-misc.png differ